简体   繁体   English

在 React jsx 中将 props 传递为 generics

[英]Passing props in React jsx as generics

In my react app i want to pass a specific interface as a generic into a unspecific component.在我的反应应用程序中,我想将特定接口作为泛型传递给非特定组件。

For example i have three specific interfaces例如我有三个特定的接口

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
}

For each of the interfaces i have a specific component ComponentA, ComponentB and ComponentC.对于每个接口,我都有一个特定的组件 ComponentA、ComponentB 和 ComponentC。 These Components need to be used in a shared component ComponentShared.这些组件需要在共享组件ComponentShared中使用。

Now for example i want in my ComponentA to return SharedComponent with the generic Type of InterfaceA and props of Type InterfaceA like this:现在例如,我希望在我的 ComponentA 中返回 SharedComponent 与 InterfaceA 的通用类型和 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>
    )

And in my sharedComponent i want to access the specific passed generic type like this:在我的 sharedComponent 中,我想访问特定传递的泛型类型,如下所示:

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

At importData.map((data:T) => data.name) it throws an error, saying T has no member of name.importData.map((data:T) => data.name)它会抛出一个错误,说 T 没有 name 的成员。 So i guess something isnt working with my generics i pass in here, because the InterfaceA im passing in as generic has the member "name" like any ohter InterfaceB and InterfaceC.所以我想我在这里传入的 generics 不能正常工作,因为作为通用传入的 InterfaceA 与任何其他 InterfaceB 和 InterfaceC 一样具有成员“名称”。 What am i doing wrong?我究竟做错了什么?

TypeScript doesn't know anything about the generic inside your function unless you inform it. TypeScript 对 function 中的泛型一无所知,除非您通知它。 You need to extend your generic T from a type that has the properties that you use inside the function.您需要从具有您在 function 中使用的属性的类型扩展您的通用T Consider this example:考虑这个例子:

TS Playground TS游乐场

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

More, based on the code in your question:更多,根据您问题中的代码:

TS Playground TS游乐场

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>
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM