Typescript接口可选属性取决于其他属性

Viv*_*Viv 11 javascript typescript

假设我们有以下打字稿界面:

interface Sample {
    key1: boolean;
    key2?: string;
    key3?: number;
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,key1始终是必需的,key2始终是可选的,而key3在key1为true时应该存在,如果key1为false则不应该存在.换句话说,密钥的出现取决于另一个密钥的值.我们怎样才能在打字稿中实现这一目标?

jca*_*alz 17

表示这种情况最直接的方法是使用类型别名而不是接口:

type Sample = {
  key1: true,
  key2?: string,
  key3: number
} | {
  key1: false,
  key2?: string,
  key3?: never
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,类型别名是您正在描述的两种类型的并集.所以a Sample应该是第一个成分(哪里key1是真的,key3是必需的)或第二个成分(哪里key1是假的,key3不存在的).

类型别名与接口类似,但它们不完全可互换.如果使用类型别名会导致某种错误,请在问题中添加有关您的用例的更多详细信息.

希望有所帮助.祝好运!


Mr *_*ton 6

我也非常喜欢 Ben Ilegbodu ( https://www.benmvp.com/blog/conditional-react-props-typescript/ ) 的做法:

在 JSX 中给出这三种不同的情况:

<Text>not truncated</Text>
<Text truncate>truncated</Text>
<Text truncate showExpand>truncated w/ expand option</Text>
Run Code Online (Sandbox Code Playgroud)

...以下是相应的 TypeScript 定义,用于在prop 存在时使该showExpanded属性成为必需的:truncate

interface CommonProps {
  children: React.ReactNode

  // ...other props that always exist
}

type TruncateProps =
  | { truncate?: false; showExpanded?: never }
  | { truncate: true; showExpanded?: boolean }

type Props = CommonProps & TruncateProps

const Text = ({ children, showExpanded, truncate }: Props) => {
  // Both truncate & showExpanded will be of
  // the type `boolean | undefined`
}```

Run Code Online (Sandbox Code Playgroud)