javascript - Typescript: es6 import typdefinition (.d.ts) från node_modules undermapp


Jag har ett npm-paket som har följande typdefinitioner (förenklade):

./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;
}

Jag använder komponenten i min React-komponent så här:

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}/>)
}

Problemet:

Typescript klagar på att det inte finns någon columnApi. Det verkar tyvärr som om den väljer fel typ från main.d.ts

Jag upptäckte att jag kan importera typen direkt från agGridReact.d.ts och använda den på det här sättet:

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

...

const grid = useRef<AgGridReactType>(null)

Fråga:

Är detta det rätta sättet att ta itu med detta problem? Kommer Typescript vara tillräckligt smart för att inte importera ./node_modules/ag-grid-react/lib/agGridReact.ts filen som skulle kunna göra att min paketstorlek ökar?

Jag har sökt mycket men kunde inte hitta något om att importera typer endast från undermappar i node_modules.

Svar #1

Jag kommer att försöka svara på detta:

Låt oss anta att det finns ett xyz-bibliotek och att det har dessa filer:

xyz/lib/main.ts:

export const test = 1000

och

xyz/main.ts:

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

Och jag skulle vilja använda xyz i min app.ts, och jag är bara medveten om dess main.ts-fil eftersom jag tror att det är huvudfilen som exporterar allt från biblioteket. Så jag kommer troligen att göra:

app.ts:

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

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

Nu går någon och kommenterar den här raden i biblioteket:

xyz/main.ts:

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

Nu, vad kommer att skrivas ut av min app.ts? Det kommer att skriva ut 1000.


Samma sak händer där med ag-grid-react. Det (ag-grid-react/main.d.ts) åsidosätter den tydligen korrekta (bättre) klassdeklarationen som finns i ag-grid-react/lib/agGridReact.d.ts. Och det är helt okej att importera från inner path.

main.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;
}

Jag kan inte riktigt säga varför ag-grid gjorde detta. Jag upptäckte detta när jag tittade på typfilerna. Jag kan också ha fel.