首页 > 解决方案 > 如何在 Typescript 中循环引用 keyof?

问题描述

我有以下类型:

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

我希望那K是测试的关键。但我得到这个错误:Type parameter 'K' has a circular constraint。我该如何解决?

更新

这种类型的使用如下:

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"
})

我想要数据参数中的类型推断create

标签: typescript

解决方案


您可以定义Settings为任意键的记录(使用预定义的 type PropertyKey = string | number | symbol),其string值:

type Settings = Record<PropertyKey, string>

保持Items不变

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

并将通用参数添加到create

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

结果函数将接受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 游乐场

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 游乐场


推荐阅读