打字稿删除可选属性

Fra*_*cis 6 typescript typescript3.0

我正在尝试为构建器构建动态类型

export type Builder<T, K extends keyof T> = {
    [P in K]: (value: T[P]) => Builder<T, K>;
} & {
    build(): Readonly<T>;
};
Run Code Online (Sandbox Code Playgroud)

如果我有一个带有可选属性的类或接口,我会收到这种错误:

$ tsc
test/OtherClass.ts:29:1 - error TS2722: Cannot invoke an object which is possibly 'undefined'.

29 OtherClass.builder().patate(Patate.AU_FOUR).build();
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

这是我的课

export class OtherClass {
    constructor(
        public literal: string | undefined,
        public patate?: Patate,
        public hello: Readonly<Hello> = {},
    ) { }

    static builder: () => Builder<OtherClass, keyof OtherClass> = builder.for(OtherClass);
}
Run Code Online (Sandbox Code Playgroud)

我期望该类型为每个属性创建一个具有非可选方法的构建器,但出于某种原因,可选性patate似乎是键而非类型固有的。我没有得到这个属性的行为literal

这对我来说似乎是个问题。我正在使用打字稿 3.1.4。还有另一种方法可以动态删除问号吗?

我尝试使用NonNullable帮助程序首先创建一个我的类型的副本,其中没有可空的内容,但patate仍然是可选的。

这是vscode给我的有效类型

(property) patate?: ((value: Patate | undefined) => Builder<OtherClass, "literal" | "patate" | "hello">) | undefined
Run Code Online (Sandbox Code Playgroud)

Nur*_*yev 8

这有帮助吗?

export type Builder<T, K extends keyof T> = {
    [P in K]-?: (value: T[P]) => Builder<T, K>;
} & {
    build(): Readonly<T>;
};
Run Code Online (Sandbox Code Playgroud)

请注意-?which 做什么你想要 - 删除可选性。

  • 当映射类型(`in` 之后的类型,确定属性集)的“约束”是`keyof T` 形式或者是受`keyof T` 约束的类型参数时,对于某些类型`T`,映射类型是“同态的”,并从 `T` 复制修饰符(可选和只读)。[此处](https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types) 对此有一些了解。 (3认同)