Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong type inference in constructor body with multiple overloads #38315

Closed
stephanemagnenat opened this issue May 4, 2020 · 4 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@stephanemagnenat
Copy link

stephanemagnenat commented May 4, 2020

TypeScript Version: 3.8.3 and nightly (tested on Playground as of May 4, 2020)

Search Terms: boolean constructor overload, constructor overload resolution

Code

class A { }

class B {
	_x: boolean;
	_y: boolean;

	constructor(x: boolean, y: boolean);
	constructor(a: A);
	constructor(xOrA: A | boolean, y?: boolean) {
		if (xOrA instanceof A) {
			this._x = true;
			this._y = true;
		} else {
			this._x = xOrA;
			this._y = y;
		}
	}
}

Expected behavior: I expect this code to compile.

Actual behavior: Compilation failure on line this._y = y; with error:

Type 'boolean | undefined' is not assignable to type 'boolean'.
Type 'undefined' is not assignable to type 'boolean'.(2322)

My understanding is that in the else branch of the if, the compiler knows that we are using the first overload, and therefore should be able to infer that y must be defined. Maybe I missed something trivial, but after searching in the documentation and online I did not find any useful hint, so I am reporting the issue.

Related Issues: none found

Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

@MartinJohns
Copy link
Contributor

Same issue as in #38211.

@stephanemagnenat
Copy link
Author

stephanemagnenat commented May 4, 2020

Ah ok, I definitely encounter a lot that design limitation these days, sorry for the noise then. Nevertheless I am a bit surprised that it is exactly the same problem because the "surface feature of the error" here is quite different than in #38211, in that issue the error was at the call site, while in this issue the error is within the constructor. I would assume that it is easier to analyse types within the constructor, but of course I do not have a full understanding of how type checking works in TS so I might well have a naive reasoning here.

@RyanCavanaugh
Copy link
Member

Duplicate #14515

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label May 5, 2020
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants