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

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)

Most upvoted comments

Even {} is assignable to object 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

function SendBlob(data: unknown, encoding: unknown) {
    if (encoding !== undefined && encoding !== 'utf8') {
        throw new Error('encoding');
    }

    // Mouse hover to see detected type 
    // When using TS v4.8.2 it is {} | undefined
    // When using TS v4.7.4 it is "utf8" | undefined
    encoding;
};

@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 …