【问题标题】:define interface: object with unknown number and name of properties定义接口:具有未知数量和属性名称的对象
【发布时间】:2019-04-03 08:22:26
【问题描述】:

我有一个对象 foo

interface Foo {
    fooId: string;
    otherStuff: any;
}

现在我有一个对象 fooCollection,它是一个包含未定义数量的 foo 的对象。每个属性都是一个等于 fooId 的字符串。如何为 fooCollection 定义准确的接口?

到目前为止,我想出了这个:

interface FooCollection {
    [key: string]: Foo;
}

-我怎么能告诉 ts 属性的数量可以是什么?

-我能不能更准确的说一下 prop 名称,说它是 fooId 而不是任何字符串?

【问题讨论】:

  • 您的索引签名已经允许任意数量的属性(零个或多个)。您能澄清一下属性名称是“fooId 而不是任何字符串”的意思吗?您的意思是每个属性的名称都应该与作为属性值的Foo 对象的fooId 字段匹配吗?
  • @Matt McCutchen “您的意思是每个属性的名称都应该与作为属性值的 Foo 对象的 fooId 字段匹配吗?” => 完全正确!

标签: typescript interface


【解决方案1】:

索引签名[key: string]: Foo 已经允许任意数量的属性(零个或多个)。

编写单个类型来强制每个属性的名称与Foo 对象的fooId 匹配,这超出了TypeScript 类型系统的能力。您可以编写一个在使用的 ID 集中通用的 FooCollection 类型,这将允许您编写一个通用函数来验证手写的 FooCollection 文字:

interface Foo<Id extends string> {
    fooId: Id;
    otherStuff: any;
}

type FooCollection<Ids extends string> = { [Id in Ids]: Foo<Id> };

function checkFooCollection<Ids extends string>
    (fooCollection: FooCollection<Ids>) { 
    return fooCollection;
}

// OK
let c1 = checkFooCollection({
    a: {fooId: "a", otherStuff: 5}
});

// Error
let c2 = checkFooCollection({
    a: {fooId: "b", otherStuff: 5}
});

但是,如果您在运行时构建 FooCollection 对象,那么这种方法不太可能比原来的方法为您提供更有意义的检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-10
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2014-11-27
    • 2015-11-09
    相关资源
    最近更新 更多