在 React jsx 中将 props 作为泛型传递

Passing props in React jsx as generics

在我的 React 应用程序中,我想将特定接口作为通用接口传递给非特定组件。

例如我有三个特定接口

SpecificInterfaces.jsx
export interface InterfaceA {
   name: string
   age: number
   ...
}

export interface InterfaceB {
    name: string
    movies: string[]
    count: number
    ...
}

export interface InterfaceC {
    name: string
    somestuff: someType
}

对于每个接口,我都有一个特定的组件 ComponentA、ComponentB 和 ComponentC。 这些组件需要在共享组件ComponentShared中使用。

例如,现在我想在我的 ComponentA 中 return SharedComponent 具有 InterfaceA 的通用类型和 Type InterfaceA 的道具,如下所示:

ComponentA.jsx
export interface Props<T> {
    importData: T[]
    ... some props... 
}

const props: Props<InterfaceA> = {
importData: importData //This is from Interface Type InterfaceA
... someProps ...
}
  return (
        <React.Fragment>
            <SharedComponent<InterfaceA> {...props} />
        </React.Fragment>
    )

在我的 sharedComponent 中,我想像这样访问特定的传递泛型类型:

SharedComponent.jsx
const SharedComponent= <T,>({
   importData,
   ...the passed Props
}: Props<T>): JSX.Element => {
importData.map((data: T) =>
    data.name) 

importData.map((data:T) => data.name)它抛出一个错误,说T没有名字的成员。所以我想我在这里传递的泛型不工作,因为作为泛型传递的 InterfaceA 与任何其他 InterfaceB 和 InterfaceC 一样具有成员“名称”。我做错了什么?

除非您通知它,否则 TypeScript 对函数内部的泛型一无所知。您需要从具有您在函数内部使用的属性的类型扩展泛型 T。考虑这个例子:

TS Playground

function logNamesBroken <T>(objects: T[]): void {
  for (const obj of objects) {
    console.log(obj.name);
/*                  ^^^^
Property 'name' does not exist on type 'T'.(2339) */
  }
}

type BaseObject = {
  name: string;
};

function logNames <T extends BaseObject>(objects: T[]): void {
  for (const obj of objects) {
    console.log(obj.name); // ok now
  }
}

更多,基于你问题中的代码:

TS Playground

import {default as React} from 'react';

interface BaseItem {
  name: string;
}

interface InterfaceA extends BaseItem {
  age: number;
}

interface Props<T extends BaseItem> {
  importData: T[];
}

const SharedComponent = <T extends BaseItem>({
  importData,
}: Props<T>): React.ReactElement => {
  return (
    <ul>
      {
        importData.map((data, index) => (
          <li key={`${index}-${data.name}`}>{data.name}</li>
        ))
      }
    </ul>
  );
};

const importData: InterfaceA[] = [{name: 'a', age: 1}, {name: 'b', age: 2}];

const props: Props<InterfaceA> = {
  importData,
};

const AnotherComponent = (): React.ReactElement => (
  <React.Fragment>
    <SharedComponent {...props} />
  </React.Fragment>
);