I have a basic interface for things that may have Ids:
interface Identifiable {
id?: number;
}
And I have a generic function that converts a record object into a thing with id:
function fromRowToObj1<T extends Identifiable>(row: { id: number; }): Partial<T> {
return { id: row.id };
// Type '{ id: number; }' is not assignable to type 'Partial<T>'.
}
I understand that this happens because there are T
s that extend Identifiable
that would make that return statement illegal. For example, the type { id: undefined }
or { id: 1 }
. So I decided to tweak the return type a bit to enforce a numeric id:
type Identified<T extends Identifiable> = {
[K in keyof T]?: K extends "id" ? number : T[K];
}
// Should give something like type C = { id?: number | undefined; ... }
function fromRowToObj2<T extends Identifiable>(row: { id: number; }): Identified<T> {
return { id: row.id };
// Type '{ id: number; }' is not assignable to type 'Identified<T>'.
}
Why, though? Which possible T
(such that T extends Identifiable
) makes it so { id: number }
is not assignable to Identified<T>
?
If there's no way to adjust the Identified
type to make this work, is there another way to type the conversion function to work with generic subtypes of Identifiable
?