Skip to content

A Type Error occurs with using a generic that extends a branded intrinsic typeΒ #55040

Closed
@RebeccaStevens

Description

@RebeccaStevens

Bug Report

πŸ”Ž Search Terms

  • generics
  • branded
  • intrinsic type

πŸ•— Version & Regression Information

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

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

/////////////////////////////////////////////////////////////////////////////////////////////
// Types

type BrandedNumber = number & {
  __branded: true
}

type OperationIO<T extends number> = T extends BrandedNumber
  ? T
  : number;

/////////////////////////////////////////////////////////////////////////////////////////////
// Function

function sub<T extends number>(
  a: OperationIO<T>,
): (b: OperationIO<T>) => OperationIO<T> {
  return (b) => (b - a) as any;
}


/////////////////////////////////////////////////////////////////////////////////////////////
// Tests

// Make sure non-branded numbers work.
const testNumbers = sub(2)(3);

// Make sure branded numbers work.
function testWithoutGenerics(a: BrandedNumber, b: BrandedNumber) {
  return sub(a)(b);
}

// Subtypes of branded numbers should work too.
function testWithGenerics<T extends BrandedNumber>(a: T, b: T) {
  return sub(a)(b); // <-- Why is this not allowed?
}

// Has correct typing dispite above error.
const testResultWithGenerics = testWithGenerics(
  2 as BrandedNumber & { __foo: 1},
  3 as BrandedNumber & { __foo: 1}
);

πŸ™ Actual behavior

TypeScript reports a type error on line 35.

πŸ™‚ Expected behavior

No error should be reported because as far I can tell, this line should be valid. Additionally, TypeScript can successfully deduce the type on line 39.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions