TypeScript: Unable to narrow union to Record in TS 4.8
Bug Report
π Search Terms
union record narrow type guard
π Version & Regression Information
- This changed between versions 4.7.4 and 4.8.2
β― Playground Link
π» Code
function isObject<T>(it: T): it is T & Record<string, unknown> {
return Object.prototype.toString.call(it) === "[object Object]";
}
declare function test(arg: Record<string, any>): void
declare const arg: (string | number | { a: "b" });
if (isObject(arg)) {
// arg is:
// - TS 4.7: {a: "b"}
// - TS 4.8: (string | number | { a: "b" }) & Record<string, unknown>
test({ ...arg }) // ERROR: Spread types may only be created from object types.(2698)
}
π Actual behavior
arg
stays as some intersection type, which TS does not recognize as an object type.
π Expected behavior
arg
gets narrowed to {a: "b"}
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 19 (13 by maintainers)
Even
{}
is assignable toobject
which is just transparently wrong. I prefer to think of the types as well-defined and the relationships as sloppy. Potato potato.Not only unions. Here is a simpler example:
https://www.typescriptlang.org/play?ts=4.8.2#code/GYVwdgxgLglg9mABAZQKZgCYCEA2cBGAFBgIZQkBci4A1mHAO5gA0i6EcGMYA5lbfSYBKRAG8AsAChEMxDGCJC7Ttx6IAhAF5N1TKmDdUGRADITbSCt4btiAOQgowABx2RE6bK9QAFgCdGRDBUBkQAUT8Av0I7ZS5eNwBuKS8AXykU2QB6LMQAWTgQAGdURB84ADdUP0QoOEQS0oxUKFRoI1qATwAHUsyZHMQAdR90aiLVRAAVZEQKgBYAOmdFgCY5KDkisVTEAB9dZoNgjH7EQZGx4smZuaWAdkX5ja3EACJHFzf9w-1DU88MjiqmSklSoKAA
@alebrozzo The TypeScript project here do not use semantic versioning, so you need to consider each minor version as most likely βbreakingβ and not just major β¦