Передача разных типов реквизита в компонент и возможность их сопоставления - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть компонент, который получил 2 разных типа для одного и того же реквизита. Свойство для компонента DisplayFiles

Как я могу заранее сообщить компоненту, что я передаю этот тип реквизита, или files реквизит будет указывать c тип типа?

Может быть, есть другой скороговоркой или способ сделать это?

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

1 Ответ

1 голос
/ 27 апреля 2020

Тип 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
}
Используйте различающееся объединение , добавляя свойство 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`
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...