首页 > 解决方案 > 将不同类型的道具传递给组件并能够映射它们

问题描述

我的组件为同一个道具接收了 2 种不同类型的组件。组件的属性DisplayFiles

我如何预先通知组件我正在传递这种道具或files道具将是特定类型的?

也许还有其他模式或方法可以做到这一点?

  isAws: boolean;
  files: (AwsValue | NormalFile)[];
}

AwsValue:

interface AwsValue {
  bucket: string;
  fileName: string;
  folderPath: string;
  lastModified: Date;
}

NormalFile:

export interface NormalFile {
  created: Date;
  fileName: string;
  folderId: number;
  instance: string;
  modified: Date;
}

export const DisplayFiles: FunctionComponent<Props> = ({
  isMetadataStep,
  files,
}) => {
  return (
    <div>
              {files.map((file: AwsValue | NormalFile) => { /* here I want tried some like isAws ? AwsValue : NormalFile, but obiously it's doesn't work */
            return (
              <FileItem
                key={file.fileName}
                title={file.fileName}
                date={file.lastModified} /* here sometimes is lastModified if AwsValue  or modified if NormalFile type */
                isSelectable={isMetadataStep}
                isSelected={selectedFile=== file.fileName}
              />
            );
          })}
    </div>
  );
};

And maybe there is possibility to pass type of property `files` in the moment of init component

Parent Component:

export const ParentOfDisplayFiles: FunctionComponent<Props> = (props) => {
  return (
    <div>
      <FileManager isMetadataStep={false} files={filteredFiles} /> {/* passed filteredFiles sometimes are AwsValues type or NormalFile */}
    </div>
  );
};`

标签: reactjstypescript

解决方案


Union 类型将允许您这样做。在这种情况下,您有两种选择:

  1. 保持这样的接口,添加一个类型 Union 像:
type File = AwsValue | NormalFile

然后添加一个带有类型保护的函数以区分:

function isAwsValue(file: File): file is AwsValue {
   return file.hasOwnProperty('bucket'); // Or whatever control you would like to do at runtime
}
  1. 使用有区别的联合,type为每个接口添加一个(或任何你喜欢的名称)属性,仍然添加一个File联合类型:
interface AwsValue {
  type: 'aws',
  // ...
}

interface NormalFile {
  type: 'normal',
  // ...
}

type File = AwsValue | NormalFile

然后你可以检查你的代码type

let file: File = /* ... */;
if (file.type === 'aws') {
  // file.bucket, etc. Now TS will suggest you props assuming `file` is an `AwsValue`
}

推荐阅读