Dont create a union type to infer conditional type branches (#30010)

This commit is contained in:
Wesley Wigham 2019-02-26 13:43:41 -08:00 committed by GitHub
parent 2533d8294e
commit 288851066b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 202 additions and 1 deletions

View File

@ -14519,7 +14519,8 @@ namespace ts {
inferFromTypes(getFalseTypeFromConditionalType(<ConditionalType>source), getFalseTypeFromConditionalType(<ConditionalType>target));
}
else if (target.flags & TypeFlags.Conditional) {
inferFromTypes(source, getUnionType([getTrueTypeFromConditionalType(<ConditionalType>target), getFalseTypeFromConditionalType(<ConditionalType>target)]));
inferFromTypes(source, getTrueTypeFromConditionalType(<ConditionalType>target));
inferFromTypes(source, getFalseTypeFromConditionalType(<ConditionalType>target));
}
else if (target.flags & TypeFlags.UnionOrIntersection) {
for (const t of (<UnionOrIntersectionType>target).types) {

View File

@ -0,0 +1,39 @@
//// [conditionalTypeRelaxingConstraintAssignability.ts]
export type ElChildren =
| ElChildren.Void
| ElChildren.Text;
export namespace ElChildren {
export type Void = undefined;
export type Text = string;
}
type Relax<C extends ElChildren> = C extends ElChildren.Text ? ElChildren.Text : C;
export class Elem<
C extends ElChildren,
> {
constructor(
private children_: Relax<C>,
) {
}
}
new Elem(undefined as ElChildren.Void);
new Elem('' as ElChildren.Text);
new Elem('' as ElChildren.Void | ElChildren.Text); // error
new Elem('' as ElChildren); // error
//// [conditionalTypeRelaxingConstraintAssignability.js]
"use strict";
exports.__esModule = true;
var Elem = /** @class */ (function () {
function Elem(children_) {
this.children_ = children_;
}
return Elem;
}());
exports.Elem = Elem;
new Elem(undefined);
new Elem('');
new Elem(''); // error
new Elem(''); // error

View File

@ -0,0 +1,73 @@
=== tests/cases/compiler/conditionalTypeRelaxingConstraintAssignability.ts ===
export type ElChildren =
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
| ElChildren.Void
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Void : Symbol(ElChildren.Void, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 3, 29))
| ElChildren.Text;
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Text : Symbol(ElChildren.Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
export namespace ElChildren {
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
export type Void = undefined;
>Void : Symbol(Void, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 3, 29))
export type Text = string;
>Text : Symbol(Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
}
type Relax<C extends ElChildren> = C extends ElChildren.Text ? ElChildren.Text : C;
>Relax : Symbol(Relax, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 6, 1))
>C : Symbol(C, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 11))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>C : Symbol(C, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 11))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Text : Symbol(ElChildren.Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Text : Symbol(ElChildren.Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
>C : Symbol(C, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 11))
export class Elem<
>Elem : Symbol(Elem, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 83))
C extends ElChildren,
>C : Symbol(C, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 10, 18))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
> {
constructor(
private children_: Relax<C>,
>children_ : Symbol(Elem.children_, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 13, 14))
>Relax : Symbol(Relax, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 6, 1))
>C : Symbol(C, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 10, 18))
) {
}
}
new Elem(undefined as ElChildren.Void);
>Elem : Symbol(Elem, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 83))
>undefined : Symbol(undefined)
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Void : Symbol(ElChildren.Void, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 3, 29))
new Elem('' as ElChildren.Text);
>Elem : Symbol(Elem, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 83))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Text : Symbol(ElChildren.Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
new Elem('' as ElChildren.Void | ElChildren.Text); // error
>Elem : Symbol(Elem, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 83))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Void : Symbol(ElChildren.Void, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 3, 29))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))
>Text : Symbol(ElChildren.Text, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 4, 31))
new Elem('' as ElChildren); // error
>Elem : Symbol(Elem, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 8, 83))
>ElChildren : Symbol(ElChildren, Decl(conditionalTypeRelaxingConstraintAssignability.ts, 0, 0), Decl(conditionalTypeRelaxingConstraintAssignability.ts, 2, 20))

View File

@ -0,0 +1,64 @@
=== tests/cases/compiler/conditionalTypeRelaxingConstraintAssignability.ts ===
export type ElChildren =
>ElChildren : ElChildren
| ElChildren.Void
>ElChildren : any
| ElChildren.Text;
>ElChildren : any
export namespace ElChildren {
export type Void = undefined;
>Void : undefined
export type Text = string;
>Text : string
}
type Relax<C extends ElChildren> = C extends ElChildren.Text ? ElChildren.Text : C;
>Relax : Relax<C>
>ElChildren : any
>ElChildren : any
export class Elem<
>Elem : Elem<C>
C extends ElChildren,
> {
constructor(
private children_: Relax<C>,
>children_ : Relax<C>
) {
}
}
new Elem(undefined as ElChildren.Void);
>new Elem(undefined as ElChildren.Void) : Elem<undefined>
>Elem : typeof Elem
>undefined as ElChildren.Void : undefined
>undefined : undefined
>ElChildren : any
new Elem('' as ElChildren.Text);
>new Elem('' as ElChildren.Text) : Elem<string>
>Elem : typeof Elem
>'' as ElChildren.Text : string
>'' : ""
>ElChildren : any
new Elem('' as ElChildren.Void | ElChildren.Text); // error
>new Elem('' as ElChildren.Void | ElChildren.Text) : Elem<ElChildren>
>Elem : typeof Elem
>'' as ElChildren.Void | ElChildren.Text : ElChildren
>'' : ""
>ElChildren : any
>ElChildren : any
new Elem('' as ElChildren); // error
>new Elem('' as ElChildren) : Elem<ElChildren>
>Elem : typeof Elem
>'' as ElChildren : ElChildren
>'' : ""

View File

@ -0,0 +1,24 @@
// @strict: true
export type ElChildren =
| ElChildren.Void
| ElChildren.Text;
export namespace ElChildren {
export type Void = undefined;
export type Text = string;
}
type Relax<C extends ElChildren> = C extends ElChildren.Text ? ElChildren.Text : C;
export class Elem<
C extends ElChildren,
> {
constructor(
private children_: Relax<C>,
) {
}
}
new Elem(undefined as ElChildren.Void);
new Elem('' as ElChildren.Text);
new Elem('' as ElChildren.Void | ElChildren.Text); // error
new Elem('' as ElChildren); // error