保留`?:`类型是可选的

  • 本文关键字:类型 保留 typescript
  • 更新时间 :
  • 英文 :


我创建了一个类型,它使除了我特别选择的属性之外的所有属性都不需要。

export type OptionalProps<Input, Excl extends keyof Input> = {
[P in Exclude<keyof Input, Excl>]: Input[P];
} &
Optional<Input>;

问题是,如果我不直接指定?:属性,就会定义它们。

我尝试了undefined extends Input[P] ? '' : Input[P],但没有成功,它只是将''指定为类型。指定undefined会迫使我始终提供undefined。

不确定如何在[]之外进行映射

游乐场

如果你想获得一个类型T及其键K的并集,并生成一个新类型,其中K中键的属性不变,但K中没有的属性都是可选的,我倾向于这样写:

type PartialExceptFor<T, K extends keyof T> =
Pick<T, K> & Partial<Omit<T, K>>;

在这里,我们只是使用提供的实用程序类型,如PickPartialOmit来组成您要查找的类型。让我们测试一下:

interface Foo {
a: string;
b: number;
c?: string;
d?: number;
}
type FB = PartialExceptFor<Foo, "b" | "d">;
// type FB = Pick<Foo, "b" | "d"> & Partial<Pick<Foo, "a" | "c">>

这是正确的,尽管很难通过查看该类型的IntelliSense快速信息来判断。处理此问题的一种方法是强制编译器遍历属性并生成一个单独的扩展对象类型:

type PartialExceptFor<T, K extends keyof T> =
Pick<T, K> & Partial<Omit<T, K>> extends infer O ? { [P in keyof O]: O[P] } : never;

CCD_ 12部分使用条件类型中的推理来";复制";类型转换为一个新的类型参数O,然后我们通过{ [P in keyof O]: O[P] }将每个属性映射到它自己。

现在IntelliSense中的快速信息为您提供以下信息:

type FB = PartialExceptFor<Foo, "b" | "d">;
/* type FB = {
b: number;
d?: number | undefined;
a?: string | undefined;
c?: string | undefined;
} */

这就是我们想要的。属性bd尚未更改(b仍然是必需的,d仍然是可选的(,但属性的其余部分ac已变为可选的。

游乐场链接到代码

最新更新