I don’t understand why this code errors. Could someone help me? I have looked all around stack overflow and found a lot of way too specific examples of this, but I don’t understand the most basic question. Why can’t Data, which extends {}, be assigned to {}? Does {} != {}?
function fn<Data extends {}>(data: Data = {}) { }
// ^^^^^^^^^^^^^^^^^
// Type '{}' is not assignable to type 'Data'.
Type ‘{}’ is not assignable to type ‘Data’. ‘{}’ is assignable to the constraint of type ‘Data’, but ‘Data’ could be instantiated with a different subtype of constraint ‘{}’.ts(2322)
>Solution :
Because the type of Data could be something that requires properties not present in {}.
Say, for example, you create the following interface:
interface FooData {
foo: string
}
We know we cannot do this:
const data: FooData = {};
// ^^ - missing required property `foo: string`
Yet that’s exactly what you are attempting in your fn declaration when you set the default value to {}. In TypeScript’s words:
‘{}’ is assignable to the constraint of type ‘Data’, but ‘Data’ could be instantiated with a different subtype of constraint ‘{}’.
In this case, FooData is the "different subtype of constraint ‘{}’" that requires property foo, which is not present on {}. {} does not guarantee that the type parameter passed to Data will be satisfied by {}, so {} is not allowed as a default.
You probably want to extend type Record<string, any> instead. {}, the empty type, is often not what you want (see here).