在TypeScript中,为具有必需属性的任何对象定义一种类型

时间:2019-08-16 09:14:42

标签: typescript

说我有一个函数,该函数采用某种具有name属性的对象。它不关心对象上的其他属性,只关心它的类型为name的{​​{1}},因此它应该接受符合此条件的任何对象类型。

是否有定义这种类型的简单方法?我最接近的是扩展由string构造的类型,但这似乎有点不雅致:

Record

1 个答案:

答案 0 :(得分:2)

您不需要为此做任何特殊的事情。这将定义必需的属性:

interface ThingWithName {
    name: string
}

function greet(thing: ThingWithName) {
    return `hello, ${thing.name}`
}

greet({name: ''}) // fine
let x = {name: '', age: 27};
greet(x) // also fine

Play

您可能要面对的是多余的属性检查,当对象文字直接分配给特定的类型引用时,多余的属性检查会禁止额外的属性。因此,在上面的代码中:greet({name: '', age: 27})将是一个错误。

您可以通过以下几种方法之一来解决此限制。

最安全的方法是使用通用类型参数:

interface ThingWithName {
    name: string
}

function greet<T extends ThingWithName>(thing: T) {
    return `hello, ${thing.name} ${thing.age}` // age is invalid
}

greet({name: ''}) // fine
greet({name: '', age: 27}) // also fine

Play

如果您希望能够使用string索引到对象中,那么您发现扩展记录的解决方案是可以的(使用索引签名可以达到相同的效果):

interface ThingWithName extends Record<string, any> {
    name: string
}

function greet(thing: ThingWithName) {
    return `hello, ${thing.name} ${thing.age}` // age is valid, so be ware you can dot into thing with any prop 
}

greet({name: ''}) // fine
greet({ }) // err
greet({name: '', age: 27}) // also fine

Play