代码之家  ›  专栏  ›  技术社区  ›  user1713450

Polymorphic React组件在IDE中具有错误的类型推断

  •  0
  • user1713450  · 技术社区  · 3 年前
    declare const MyComponent = <A extends {id: bigint|number}>(props: MyProps<A>) => React.FC<{}>
    
    interface MyProps<A extends {id: number}> {
      data: A[]
      orderBy: keyof A
    }
    
    declare const x: { id: number, foo: string }[]
    
    const Foo = () => {
      <MyComponent data={x} orderBy="foo"/> // <-- Type 'keyof A' is not assignable to type 'never'
    }
    

    我认为这是因为TS未能从 data 那个类型是类型 { id: number, ... } 因此它认为 数据 属于类型 {} 因此 keyof A 属于类型 never (所以 orderBy 根本不可能是任何东西)。

    所以我的问题是,除了 // @ts-ignore 就在上面?我可以手动指定的类型吗 A 不知怎么在我的TSX里?我不能做任何类似的事情

    import { MyComponent } from ...
    declare const specify = <A>() => typeof MyComponent<A> // <-- error here because of the <A> part after MyComponent
    
    const Foo = <A ...>() => {
      const SpecialMyComponent = specify<A>()
      return <SpecialMyComponent .../>
    }
    

    似乎你不能在TSX中执行这些泛型,而TS不认为它是TSX,而不是指定泛型的值。

    0 回复  |  直到 3 年前
        1
  •  0
  •   jsejcksn    3 年前

    我在下面的代码中提供了解释性注释。如果有不清楚的地方,请随时回复:

    TS Playground

    import {default as React} from 'react';
    
    // bigint was missing from this union in MyProps:
    type ID = {
      id: bigint | number;
    };
    
    type MyProps <A extends ID> = {
      data: A[];
      orderBy: keyof A;
    };
    
    // Suggestion: use React.ReactElement if you're rendering JSX or a component that does:
    declare function MyComponent <A extends ID>(props: MyProps<A>): React.ReactElement;
    
    declare const x: { id: number; foo: string; }[];
    
    const Foo = () => {
      <MyComponent data={x} orderBy="foo"/> // ok
    }
    
    
    // And, finally... yes, you CAN use generics with TSX!
    
    type Y = { id: bigint; baz: string[]; };
    declare const y: Y[];
    
    const Bar = () => {
      <MyComponent<Y> data={y} orderBy="baz" /> // ok
    };