简体   繁体   English

推断数组对象的键类型

[英]Infer the key type of the array object

I have the next example我有下一个例子

type C = [
    {name: 'a'},
    {name: 'b'},
    {name: 'c'},
]

And I want to infer a new type SomeType based on the type C described above like this我想根据上面描述的类型C推断出一个新类型SomeType像这样

const a: SomeType<C> = {
    a: () => {},
    b: () => {},
    c: () => {},
}

And so that there is a check of all keys.这样就可以检查所有密钥。 The following example must be invalid下面的例子一定是无效的

const a: SomeType<C> = {
    a: () => {},
    b: () => {},
    // Error. "c" is not defined
}

I have tried to solve my problem like in the playground , but my solution doesn't check presence all keys我试图像在操场上一样解决我的问题,但我的解决方案没有检查所有键是否存在

You need a mapped type to map from the array type to your desire type:您需要一个映射类型来从数组类型映射到您想要的类型:

type SomeType<T extends Array<{ name: string }>> = {
  [P in T[number]['name']]: () => void
}

Playground Link 游乐场链接

Here's one approach:这是一种方法:

type SomeType<T extends { [k: number]: { name: string } }> =
    Record<T[number]['name'], () => void>;

It accepts T constrained to a type with a numeric index signature (such as an array) whose elements have a name property of type string .它接受T 约束为具有数字索引签名的类型(例如数组),其元素具有string类型的name属性。

And it evaluates to a type whose keys are those string -assignable name properties (using T[number]['name'] , a series of indexed access types ), and whose value types are a function (I chose () => void but you might have a more specific type you care about).它评估为一个类型,其键是那些string可分配的name属性(使用T[number]['name'] ,一系列索引访问类型),其值类型是一个函数(我选择() => void但你可能有一个更具体的你关心的类型)。 This uses the Record<K, V> utility type to represent an object type with keys of type K and values of types V .这使用Record<K, V>实用程序类型来表示具有类型K的键和类型V的值的对象类型。

Let's try it out:让我们试一试:

const ports: SomeType<C> = { // error, missing b and c
    a: () => { },
}    

const ports2: SomeType<C> = {
    unknownkey: () => { }, // error, unknown key in object literal 
                           // (note, only errors for object literal)
}

const ports3: SomeType<C> = { // okay
    a: () => { },
    c: () => { },
    b: () => { },
}

Looks good!看起来不错!

Playground link to code Playground 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM