javascript - typescript :es6 从 node_modules 子文件夹导入类型定义(.d.ts)

标签 javascript reactjs typescript ag-grid

我有一个具有以下类型定义(简化)的 npm 包:

./node_modules/ag-grid-react/main.d.ts

export declare class AgGridReact extends Component<AgGridReactProps, {}> {}

./node_modules/ag-grid-react/lib/agGridReact.d.ts

export declare class AgGridReact extends Component<AgGridReactProps, {}> {
    gridOptions: GridOptions;
    api: GridApi | null;
    columnApi: ColumnApi;
}

我在我的 React 组件中使用这个组件是这样的:

import { AgGridReact } from 'ag-grid-react'

const HelpRequests= () => {
  const grid = useRef<AgGridReact>(null)

  if (grid.current) console.log(grid.current.columnApi)

  return (<AgGridReact ref={grid}/>)
}

问题:

Typescript 确实提示没有 columnApi。它似乎很遗憾地从 main.d.ts 中选择了错误的类型

我发现我可以直接从 agGridReact.d.ts 导入类型并像这样使用它:

import {AgGridReact as AgGridReactType} from 'ag-grid-react/lib/agGridReact'

...

const grid = useRef<AgGridReactType>(null)

问题:

这是解决此问题的正确方法吗? typescript 是否足够聪明,不会导入 ./node_modules/ag-grid-react/lib/agGridReact.ts 文件,这可能会导致我的包大小增加?

我搜索了很多但找不到任何有关仅从 node_modules 子文件夹导入类型的信息。

最佳答案

我会尝试回答这个问题:

假设有一个 xyz 库并且它有这些文件:

xyz/lib/main.ts:

export const test = 1000

xyz/main.ts:

export * from './lib/main.ts'
export const test = 'foo bar'

我想在我的 app.ts 中使用 xyz,我只知道它的 ma​​in.ts 文件,因为我认为它是从库中导出所有内容的主文件。所以我最有可能这样做:

app.ts:

import { test } from './xyz/main'

console.debug(test) // it will print 'foo bar'

现在,有人去评论库中的这一行:

xyz/main.ts:

export * from './lib/main.ts'
// export const test = 'foo bar'

现在,我的 app.ts 会打印什么?它将打印 1000


ag-grid-react 也发生了同样的事情。它 (ag-grid-react/main.d.ts) 覆盖 ag-grid-react/lib 中明显正确(更好)的类声明/agGridReact.d.ts。从内部路径导入是完全没问题的。

ma​​in.d.ts:

export * from './lib/agGridReact'; // it is exporting from innner path too
export declare class AgGridColumn extends Component<AgGridColumnProps | AgGridColumnGroupProps, {}> { // and overriding here at the same time
}

agGridReact.d.ts:

export declare class AgGridReact extends Component<AgGridReactProps, {}> {
    props: any;
    state: any;
    static propTypes: any;
    gridOptions: GridOptions;
    changeDetectionService: ChangeDetectionService;
    api: GridApi | null;
    columnApi: ColumnApi;
    portals: ReactPortal[];
    hasPendingPortalUpdate: boolean;
    destroyed: boolean;
    protected eGridDiv: HTMLElement;
    private static MAX_COMPONENT_CREATION_TIME;
    constructor(props: any, state: any);
    render(): React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)>;
    createStyleForDiv(): any;
    componentDidMount(): void;
    waitForInstance(reactComponent: ReactComponent, resolve: (value: any) => void, runningTime?: number): void;
    mountReactPortal(portal: ReactPortal, reactComponent: ReactComponent, resolve: (value: any) => void): void;
    batchUpdate(callback?: any): any;
    destroyPortal(portal: ReactPortal): void;
    private getStrategyTypeForProp;
    shouldComponentUpdate(nextProps: any): boolean;
    componentDidUpdate(prevProps: any): void;
    processPropsChanges(prevProps: any, nextProps: any): void;
    private extractDeclarativeColDefChanges;
    private extractGridPropertyChanges;
    componentWillUnmount(): void;
    isDisableStaticMarkup(): boolean;
}

我不能确切地说出为什么 ag-grid 这样做。我在查看打字文件时发现了这一点。我也可能不正确。

关于javascript - typescript :es6 从 node_modules 子文件夹导入类型定义(.d.ts),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61944463/

相关文章:

javascript - 为什么我的代码从 ES5 语法转换为 ES6 语法时不起作用?

javascript - 如何在 React v16 中手动调用自定义 PropType 验证器

typescript - 类型 `{ [key in string]: boolean };` 和 `{ [key : string]: boolean };` 是否等效?

javascript - 从 nodejs 将 "$binary"键插入 mongodb 导致 must not start with '$' 错误

javascript - NodeJS 结合对象数组范围属性

javascript - Dated-fns 无法解析 ISO 日期

javascript - 如何避免 Backbonejs View 中的双重事件绑定(bind)?

reactjs - 基于状态的条件渲染

typescript - 无法模拟 API 请求

javascript - 使用 TypeScript 扩展 Breeze 实体