Closed
Description
Bug Report
π Search Terms
π Version & Regression Information
- Regression in: 4.7.0-dev.20220325
- Works in 4.7.0-dev.20220323
β― Playground Link
Playground currently doesn't show the error:
π» Code
function deepEquals<T>(a: T, b: T): boolean {
if (typeof a !== 'object' || typeof b !== 'object' || !a || !b) {
return false;
}
if (Array.isArray(a) || Array.isArray(b)) {
return false;
}
if (Object.keys(a).length !== Object.keys(b).length) { // Error here
return false;
}
return true;
}
π Actual behavior
The calls to Object.keys
generate errors:
No overload matches this call.
Overload 1 of 2, '(o: {}): string[]', gave the following error.
Argument of type 'T' is not assignable to parameter of type '{}'.
Overload 2 of 2, '(o: object): string[]', gave the following error.
Argument of type 'T' is not assignable to parameter of type 'object'.
π Expected behavior
No errors
Activity
mjbvz commentedon Mar 29, 2022
This code previously worked for us in VS Code but is now causing around 11 errors in our codebase. Not sure if simply adding a
extends object
constraint is the correct fix in all cases[-]Types no longer narrowed as expected [/-][+]Generic type no longer narrowed as expected without `extends object`[/+]whzx5byb commentedon Mar 29, 2022
It seems to be caused by #48366, which is tagged as "Breaking Change".
Now you can't assign a unconstrained type parameter
T
toT extends {}
orT extends object
. See also #37388DanielRosenwasser commentedon Mar 29, 2022
CC @weswigham
Looks like the following will work
and so will
but not
Note that the first two only likely work due to @ahejlsberg's change in #43183. I don't know if we're willing to do something special for
unknown
or all non-unions.Pick up latest TS for building VS Code
mjbvz commentedon Mar 29, 2022
Also seeing this in the
@playwright/test
package. See this issue for repo steps and details about the errorDanielRosenwasser commentedon Apr 5, 2022
Playing around with a fix here FWIW
#48576
arnold-O commentedon Feb 9, 2023
The Generic type without constraint is vague, hence with the extends keyword you clearly state what you want that Generic type to be, which is the reason for Typescript.