Skip to content

instanceof narrowing should respect type parameter bounds for covariant typesΒ #63332

@ethanresnick

Description

@ethanresnick

πŸ”Ž Search Terms

instanceof typeguard type parameter bounds

πŸ•— Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about instanceof

⏯ Playground Link

https://www.typescriptlang.org/play/?target=99#code/KYDwDg9gTgLgBAYwDYEMDOa4GECuaYQC2AolFNADxYQAmwcoMwAdjZgEQCC7cAPnOwBC7AHwMQTVplLkocAN4AoOHCjAUNCMyQBPRLWAAubAYDci5fub4oOBASgAKCGBgBLLWmPz9dY9ToAGjhCYAwUAHMjOBs3Zgi4AF8ASgVLFTQcMGAnF3dPADpQ8Kjk8xUVGAALNzQChAM4AF44PI9rerNLRMUexTpkFDUrfDgQYxxmAGtmCAB3ZnNFNwAzRxA4OPwUZgRgCBXsPAISMmhUpRUQTrpFAHo7lQA9AH5exSA

πŸ’» Code

export class CustomError<Code extends "A" | "B"> extends Error {
  readonly code: Code;

  constructor(options: { code: Code, message: string }) {
    super(options.message);
    this.code = options.code;
  }
}

declare const x: unknown;

if(x instanceof CustomError) {
  x.code // inferred as any
}

πŸ™ Actual behavior

x.code is any, because x is only narrowed to CustomError<any>.

πŸ™‚ Expected behavior

It would be much more useful to narrow Code in CustomError to its bounds, rather than to any. So x would become CustomError<"a" | "b"> and then x.code could usefully be "A" | "B"

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions