TypeScript移除可选属性

7

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

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

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

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

29 OtherClass.builder().patate(Patate.AU_FOUR).build();
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~

这是我的班级

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

    static builder: () => Builder<OtherClass, keyof OtherClass> = builder.for(OtherClass);
}

我原本希望该类型会创建一个构建器,其中包含每个属性的非可选方法,但由于某种原因,“patate”的可选性似乎与键而非类型紧密相关。使用属性“literal”时,我没有遇到这种行为。
在我看来,这看起来像是一个问题。我正在使用typescript 3.1.4版本。是否有另一种方法可以动态地移除这个问号?
我尝试过使用“NonNullable”帮助程序先创建一个类型副本,其中没有任何可空项,但“patate”仍然是可选的。
这是vscode给我的有效类型。
(property) patate?: ((value: Patate | undefined) => Builder<OtherClass, "literal" | "patate" | "hello">) | undefined
1个回答

12
这有帮助吗?
export type Builder<T, K extends keyof T> = {
    [P in K]-?: (value: T[P]) => Builder<T, K>;
} & {
    build(): Readonly<T>;
};

请注意-?,它会使选项变得非必需。

是的,谢谢,但是你知道它为什么从键名继承可选性吗? - Francis
3
当映射类型(在in关键字后的类型,决定属性集合)的“约束条件”为keyof T形式,或者是某个类型T的限定为keyof T的类型参数时,该映射类型是“同态”的并从T中复制修饰符(可选和只读)。这里有详细说明链接 - Matt McCutchen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接