简体   繁体   English

如何在 Typescript 中循环引用 keyof?

[英]How to circular reference keyof in Typescript?

I have this following type:我有以下类型:

type Test = {
    [K in keyof Test]: string
}

I want that K to be the key of Test.我希望K成为测试的关键。 But I get this error: Type parameter 'K' has a circular constraint .但我得到这个错误: Type parameter 'K' has a circular constraint How do I fix this?我该如何解决?

UPDATE更新

This type is used as follows:这种类型的使用如下:

type Settings = {
    [K in keyof Settings]: string
}
type Items<T> = Record<keyof T, any>
function create(settings: Settings, data: Items<Settings>) {
    
}

create({
    name: "tt"
}, {
    name: "aaaa"
})

I want the type inference in data parameter in create我想在create中的数据参数中进行类型推断

You could define Settings as a record of arbitrary keys (using the predefined type PropertyKey = string | number | symbol ), with string values:您可以将Settings定义为任意键的记录(使用预定义的类型PropertyKey = string | number | symbol ),带有string值:

type Settings = Record<PropertyKey, string>

keep Items the same保持Items相同

type Items<T> = Record<keyof T, any>

and add a generic parameter to create :并添加一个通用参数来create

function create<S extends Settings>(settings: S, data: Items<S>) {
}

The resulting function will accept data objects that have the same keys as settings, and throw an error otherwise:生成的 function 将接受与设置具有相同键的data对象,否则抛出错误:

create({name: "tt", x: 'x'}, {name: 42, x: true}) // OK

create({name: "tt", x: 'x'}, {name: 42})
// ERROR: Property 'x' is missing in type '{ name: number; }' but required
// in type 'Items<{ name: string; x: string; }>

create({name: "tt", x: 'x'}, {name: 42, x: true, y: 1})
// ERROR: Object literal may only specify known properties, and 'y' does
// not exist in type 'Items<{ name: string; x: string; }>'.

TypeScript playground TypeScript操场

Support for autocomplete on data properties can be achieved by adding a generic key parameter, which will allow partial data objects:可以通过添加通用键参数来支持data属性的自动完成,这将允许部分data对象:

type Items<K extends PropertyKey> = Record<K, any>

function create<S extends Settings, K extends keyof S>(settings: S, data: Items<K> ) {
}

create({name: "tt", x: 'x'}, {name: 42, x: true}) // OK

create({name: "tt", x: 'x'}, {name: 42}) // OK: data can omit properties 

create({name: "tt", x: 'x'}, {name: 42, x: true, y: 1})
// ERROR: Object literal may only specify known properties, and 'y' does
// not exist in type 'Items<{ name: string; x: string; }>'.

TypeScript playground TypeScript操场

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

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