I have defined a simple ID type, and a type that should represent all suitable properties from a given object type that might hold this ID:
export type MyId = string | number;
export type MyIdProp<T extends object> = {
[K in keyof T]: T[K] extends (MyId | undefined) ? K : never
}[keyof T];
I think this should be correct:
MyIdProp
assumes, for a given object type T
, an object type that maps properties of T to themselves, but only those properties whose value is assignable to MyId
or undefined
.
And then, only the properties listed in this assumed object are taken into account to form the resulting union.
Now, I’m trying to retrieve the ID value from a given object in a generic function:
function doSomething<T extends object>(obj: T, idAttr: MyIdProp<T>): MyId {
const objId = obj[idAttr];
if (objId === undefined || objId === null) {
throw new Error('No ID supplied!');
}
return objId;
}
However, this fails with error 2322 on the line return objId;
, saying:
Type ‘T[MyIdProp] & {}’ is not assignable to type ‘MyId’.
Why? Where does that & {}
come from and how do I prevent this?