Having a generic function that takes a string-indexed object
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) {}
I know I could use a type guard on key
before calling wantsStringAndAny
but I would expect:
1: key
should be typed as string for sure inside wantsStringIndexedObject
2: shouldn't be allowed to call wantsStringIndexedObject
with that kind of object
I suppose that the issue comes from generic definition Obj extends { [k: string]: any }
infact any object with any index type extends a { [k: string]: any }
with 0 properties.
so, is there a way to define a generic ensuring a string-indexed-object constraint ?