TypeScript 只允许一个属性

huangapple go评论70阅读模式
英文:

Typescript allow only one property

问题

This code allows me to send in props for just one of the options but not the other, for example:

<Drawer volunteer />

现在只有3个属性,但如果有更多属性,我应该如何更加通用地编写它?

抽屉的类型声明:

type DrawerTypes =
    { volunteer: boolean } &amp; { rescues?: never } &amp; { map?: never } |
    { volunteer?: never } &amp; { rescues: boolean } &amp; { map?: never } |
    { volunteer?: never } &amp; { rescues?: never } &amp; { map: boolean };
英文:

This code allow me to send in props just one of the options but not the other, for example:

&lt;Drawer volunteer /&gt;

now it's 3 properties, but if there is more how can i write it more generic ?

The Drawer types declaration:

type DrawerTypes =
    { volunteer: boolean } &amp; { rescues?: never } &amp; { map?: never } |
    { volunteer?: never } &amp; { rescues: boolean } &amp; { map?: never } |
    { volunteer?: never } &amp; { rescues?: never } &amp; { map: boolean };

答案1

得分: 0

以下是您要翻译的内容:

可以使用映射类型来映射键,选择特定键并将其他键设置为 `never`

```ts
type OneOf<T> = {
    [K in keyof T]: Pick<T, K> & Partial<Record<Exclude<keyof T, K>, never>>;
}[keyof T]

新定义的 DrawerTypes 将是

type DrawerTypes = OneOf<{ volunteer: boolean; rescues: boolean; map: boolean }>;

诚然,DrawerTypes 的工具提示并不特别有帮助,所以如果您添加这个额外的部分,

type OneOf<T> = {
    [K in keyof T]: Pick<T, K> & Partial<Record<Exclude<keyof T, K>, never>>;
}[keyof T] extends infer O ? { [K in keyof O]: O[K] } : never;

您可以看到 DrawerTypes 等同于

type DrawerTypes = {
    volunteer: boolean;
    rescues?: undefined;
    map?: undefined;
} | {
    rescues: boolean;
    volunteer?: undefined;
    map?: undefined;
} | {
    map: boolean;
    volunteer?: undefined;
    rescues?: undefined;
}

这与您原始定义的 DrawerTypes 相同。

Playground


注意:`key?: undefined` 等同于没有 `exactOptionalPropertyTypes` 的 `key?: never`。

<details>
<summary>英文:</summary>

You can use a mapped type to map over the keys, picking the specific key and making the others `never`:

```ts
type OneOf&lt;T&gt; = {
    [K in keyof T]: Pick&lt;T, K&gt; &amp; Partial&lt;Record&lt;Exclude&lt;keyof T, K&gt;, never&gt;&gt;;
}[keyof T]

The new definition of DrawerTypes would be

type DrawerTypes = OneOf&lt;{ volunteer: boolean; rescues: boolean; map: boolean }&gt;;

Admittedly, the tooltip of DrawerTypes is not particularly helpful, so if you add this extra bit,

type OneOf&lt;T&gt; = {
    [K in keyof T]: Pick&lt;T, K&gt; &amp; Partial&lt;Record&lt;Exclude&lt;keyof T, K&gt;, never&gt;&gt;;
}[keyof T] extends infer O ? { [K in keyof O]: O[K] } : never;

you can see that DrawerTypes is equivalent to

type DrawerTypes = {
    volunteer: boolean;
    rescues?: undefined;
    map?: undefined;
} | {
    rescues: boolean;
    volunteer?: undefined;
    map?: undefined;
} | {
    map: boolean;
    volunteer?: undefined;
    rescues?: undefined;
}

which is the same as your original definition of DrawerTypes.

Playground


note: key?: undefined is equivalent to key?: never without exactOptionalPropertyTypes.

huangapple
  • 本文由 发表于 2023年3月21日 01:12:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75793325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定