Skip to content

Type confusion when function returns a unionΒ #51180

Open
@bogdanb

Description

@bogdanb

Bug Report

πŸ”Ž Search Terms

union return type

πŸ•— Version & Regression Information

  • This changed between versions 3.3.3333 and 3.5.1

The same bug happens every version newer than 3.3.3 that I tried, including 4.8.4 and nightly.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

interface TestType<P> {
  prop: P;
}

interface StringType extends TestType<string> {}

interface NumberType extends TestType<number> {}

interface UnknownType extends TestType<unknown> {}

interface ResultOne<G extends UnknownType> {
  type: "one";
  value: G["prop"];
}

interface ResultTwo<G extends UnknownType> {
  type: "two";
  other: G["prop"];
}

function callback<G extends UnknownType>(): ResultOne<G> | ResultTwo<G> {
  const dt: ResultOne<StringType> = {
    type: "one",
    value: "abc",
  };

  return dt; // this should not be allowed, G['prop'] is not known to be a string
}

const tst = callback<NumberType>();
const shouldBeNumber: number = tst.type === "one" ? tst.value : tst.other;

console.log(
  shouldBeNumber,
  typeof shouldBeNumber,
  '<- this should say "number"'
);

πŸ™ Actual behavior

The callback happily returns the value, although its type does not match the declared return type. None of the other type annotations complain, either, but the program typing is clearly wrong. The log at the end makes it clear that the behavior does not match the declared types.

πŸ™‚ Expected behavior

The line that says return dt; should have a type error, because ResultOne<StringType> is not a valid match for the return type of the function.

Interestingly, v3.3.3 in Playground does report the correct error exactly on that line:

const dt: ResultOne<StringType>
Type 'ResultOne<StringType>' is not assignable to type 'ResultOne<G> | ResultTwo<G>'.
  Type 'ResultOne<StringType>' is not assignable to type 'ResultOne<G>'.
    Type 'StringType' is not assignable to type 'G'.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions