拥有一个带有字符串索引对象的泛型函数
function wantsStringIndexedObject<
Obj extends { [k: string]: any },
K extends keyof Obj
>(obj: Obj, key: K) {
const _ktype = typeof key
// const ktype: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
const val = obj[key]
wantsStringAndAny(key, val)
// Argument of type 'K' is not assignable to parameter of type 'string'.
// Type 'keyof Obj' is not assignable to type 'string'.
// Type 'string | number | symbol' is not assignable to type 'string'.
// Type 'number' is not assignable to type 'string'.
// (parameter) key: K extends keyof Obj
}
// no error here
wantsStringIndexedObject({
1: 10,
[Symbol()]:1
}, 1)
function wantsStringAndAny(str: string, v:any) {}
我知道在调用key
之前我可以在wantsStringAndAny
上使用类型防护,但我希望:
1:key
应该在wantsStringIndexedObject
内输入字符串
2:不应该允许用这种物体调用wantsStringIndexedObject
我想问题来自通用定义qazxsw poi 实际上,具有任何索引类型的对象扩展了具有0个属性的qazxsw poi。
那么,有没有办法定义一个确保字符串索引对象约束的泛型?
您可以通过使用Obj extends { [k: string]: any }
条件类型来过滤{ [k: string]: any }
的键来确保键是字符串类型:
Extract
通常,约束是类型必须实现的最小契约,没有什么能阻止实际类型在其键中包含符号。字符串索引实际上也允许使用字符串和数字进行索引,因此在您的假设下也允许使用数字。
如果您还想禁止Obj
中的任何数字或符号键,您可以执行以下操作:
function wantsStringAndAny(str: string, v:any) {
}
function wantsStringIndexedObject<
Obj extends object,
K extends Extract<keyof Obj, string>
>(obj: Obj, key: K) {
const _ktype = typeof key
const val = obj[key]
wantsStringAndAny(key, val)
}
// err
wantsStringIndexedObject({
1: 10,
[Symbol()]:1
}, 1)
//ok
wantsStringIndexedObject({
"1": "",
}, "2")
这需要任何Obj
或function wantsStringIndexedObject<
Obj extends object,
K extends Extract<keyof Obj, string>
>(obj: Obj & Record<Extract<keyof Obj, number | symbol>, never>, key: K) {
const _ktype = typeof key
const val = obj[key]
wantsStringAndAny(key, val)
}
//ok
wantsStringIndexedObject({
"1": "",
}, "1")
wantsStringIndexedObject({
"1": "",
2: 0 // errr
}, "1")
键,基本上说它们应该是number
类型(可能但不太可能),你会在任何这样的键上得到一个错误。