Reputation: 917
I am having trouble using a partial on a generic type:
interface HasName {
name: string;
}
class Tools<T extends HasName> {
public create: (params: Partial<T>) => T;
createWithName = (nameArg: string) => {
this.create({ name: nameArg })
}
}
I expect this example to work because T extends HasName
should ensure that T
will have a name
field, and (params: Partial<T>)
should match any object with any subset of the keys of T
.
However, there is a typescript compilation error on the line this.create({ name: nameArg })
:
Argument of type '{ name: string; }' is not assignable to parameter of type 'Partial'.
Can someone help me understand why { name: string }
is not assignable to Partial<T>
, when it should be based on my logic above?
Thank you in advance.
Upvotes: 2
Views: 119
Reputation: 32156
In short, TypeScript is right, but as long as you're careful with what you use for T
, you should be okay to just silence the error with a cast:
this.create({ name: nameArg } as Partial<T>)
As to why TypeScript is right here, it's because you can create types that extend HasName
but for which {name: string}
isn't a valid object of that type.
The easiest example is just to make a type where name
is more specific than just string
:
interface HasSpecificName extends HasName {
name: "alice" | "bob";
}
In which case, {name: nameArg}
where nameArg
is any string isn't assignable to Partial<HasSpecificName>
since string
isn't assignable to "alice" | "bob"
.
Upvotes: 2