【问题标题】:Typescript - Force default type for additional properties in interfaceTypescript - 强制界面中其他属性的默认类型
【发布时间】:2018-04-10 18:51:12
【问题描述】:

我有一个接口,它有一些特定类型的属性

interface dummyInterface {
    propA: string,
    propB: boolean,
    propC: number,
}

属性 A 到 C 是强制性的,但这种类型的对象也可以包含任意数量的任何名称的附加属性。但是,我想强制所有附加属性为string 类型。我知道这不能通过添加类似的东西来完成

{
    .
    .
    .
    [additionalProp: string]: string
}

因为这会与 PropBPropC 相矛盾,它们分别是 booleannumber

有什么方法可以实现吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以通过类型交集来实现:

    interface MandatoryProps {
        numberProp: number;
        boolProp: boolean;
    }
    
    type TypeWithMandatoryAndOptionalProps =
        // For mandatory props:
        MandatoryProps &
        // For optionals:
        Record<string, string>;
    
    declare const foo: TypeWithMandatoryAndOptionalProps;
    
    foo.blablabla; // string
    foo.numberProp; // number
    foo.boolProp; // boolean
    

    UPD。我想我的答案有点匆忙。虽然建议的类型似乎解决了定义这种类型的问题,但使用它仍然存在很多问题(TS 维护人员在下面的 cmets 中链接的问题中解释了)。您可以尝试通过转换any 或使用Object.assign 为具有此类类型的变量分配值来解决问题:

    const foo = <TypeWithMandatoryAndOptionalProps><any>{/* ... */};
    
    // or
    
    const bar: TypeWithMandatoryAndOptionalProps = Object.assign(
       { numberProp: 1, boolProp: false },
       { blablabla: 'test' }
    );
    

    但这两个选项基本上都是技巧类型检查器,而不是为您的程序提供健全的类型系统。

    TL; DR 如下。除非您试图让类型工作在现有的 JS 程序中,否则请重新考虑您的类型。对带有键签名或Map 的对象使用单独的属性。

    感谢 @jcalz 指出 TS 问题。

    【讨论】:

    • 不,这仍然会产生错误:Property 'numberProp' is incompatible with index signature. Type 'number' is not assignable to type 'string'.
    • 我用 TS playground 检查了代码。你把索引签名放在哪里了?请注意,界面没有。还有你用的是什么版本的TS?
    • 我怀疑@DanielR 遇到了这样的问题:const foo2: TypeWithMandatoryAndOptionalProps = { boolProp: true, numberProp: 3 }。有一个 open issue 围绕这个问题,所以也许 @KirillDmitrenko 可以在答案中提到这一点。
    • @jcalz 是的,看起来像。感谢提供问题链接,更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多