mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Merge pull request #5921 from Microsoft/revert-5919-port_union_reduction_to_1.7
Revert "Port union reduction to 1.7"
This commit is contained in:
commit
564c7b448f
@ -43,8 +43,6 @@ namespace ts {
|
||||
let emptyArray: any[] = [];
|
||||
let emptySymbols: SymbolTable = {};
|
||||
|
||||
let jsxElementClassType: Type = undefined;
|
||||
|
||||
let compilerOptions = host.getCompilerOptions();
|
||||
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
|
||||
let modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
|
||||
@ -4940,6 +4938,9 @@ namespace ts {
|
||||
}
|
||||
return objectTypeRelatedTo(<ObjectType>source, <ObjectType>target, /*reportErrors*/ false);
|
||||
}
|
||||
if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
|
||||
return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
|
||||
@ -5070,6 +5071,20 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function typeParameterIdenticalTo(source: TypeParameter, target: TypeParameter): Ternary {
|
||||
if (source.symbol.name !== target.symbol.name) {
|
||||
return Ternary.False;
|
||||
}
|
||||
// covers case when both type parameters does not have constraint (both equal to noConstraintType)
|
||||
if (source.constraint === target.constraint) {
|
||||
return Ternary.True;
|
||||
}
|
||||
if (source.constraint === noConstraintType || target.constraint === noConstraintType) {
|
||||
return Ternary.False;
|
||||
}
|
||||
return isIdenticalTo(source.constraint, target.constraint);
|
||||
}
|
||||
|
||||
// Determine if two object types are related by structure. First, check if the result is already available in the global cache.
|
||||
// Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
|
||||
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
|
||||
@ -5592,20 +5607,27 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
// Check that the two signatures have the same number of type parameters. We might consider
|
||||
// also checking that any type parameter constraints match, but that would require instantiating
|
||||
// the constraints with a common set of type arguments to get relatable entities in places where
|
||||
// type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
|
||||
// particularly as we're comparing erased versions of the signatures below.
|
||||
if ((source.typeParameters ? source.typeParameters.length : 0) !== (target.typeParameters ? target.typeParameters.length : 0)) {
|
||||
let result = Ternary.True;
|
||||
if (source.typeParameters && target.typeParameters) {
|
||||
if (source.typeParameters.length !== target.typeParameters.length) {
|
||||
return Ternary.False;
|
||||
}
|
||||
for (let i = 0, len = source.typeParameters.length; i < len; ++i) {
|
||||
let related = compareTypes(source.typeParameters[i], target.typeParameters[i]);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
}
|
||||
result &= related;
|
||||
}
|
||||
}
|
||||
else if (source.typeParameters || target.typeParameters) {
|
||||
return Ternary.False;
|
||||
}
|
||||
// Spec 1.0 Section 3.8.3 & 3.8.4:
|
||||
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
|
||||
source = getErasedSignature(source);
|
||||
target = getErasedSignature(target);
|
||||
let result = Ternary.True;
|
||||
const targetLen = target.parameters.length;
|
||||
let targetLen = target.parameters.length;
|
||||
for (let i = 0; i < targetLen; i++) {
|
||||
let s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
|
||||
let t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
|
||||
@ -5906,17 +5928,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function inferFromTypes(source: Type, target: Type) {
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
// Source and target are both unions or both intersections. To improve the quality of
|
||||
// inferences we first reduce the types by removing constituents that are identically
|
||||
// matched by a constituent in the other type. For example, when inferring from
|
||||
// 'string | string[]' to 'string | T', we reduce the types to 'string[]' and 'T'.
|
||||
const reducedSource = reduceUnionOrIntersectionType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target);
|
||||
const reducedTarget = reduceUnionOrIntersectionType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source);
|
||||
source = reducedSource;
|
||||
target = reducedTarget;
|
||||
}
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
|
||||
@ -5927,7 +5938,8 @@ namespace ts {
|
||||
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
|
||||
return;
|
||||
}
|
||||
const typeParameters = context.typeParameters;
|
||||
|
||||
let typeParameters = context.typeParameters;
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
if (target === typeParameters[i]) {
|
||||
let inferences = context.inferences[i];
|
||||
@ -5999,9 +6011,12 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
source = getApparentType(source);
|
||||
if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
|
||||
(target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
|
||||
// If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members
|
||||
if (source.flags & TypeFlags.ObjectType && (
|
||||
target.flags & TypeFlags.Reference && (<TypeReference>target).typeArguments ||
|
||||
target.flags & TypeFlags.Tuple ||
|
||||
target.flags & TypeFlags.Anonymous && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
|
||||
// If source is an object type, and target is a type reference with type arguments, a tuple type,
|
||||
// the type of a method, or a type literal, infer from members
|
||||
if (isInProcess(source, target)) {
|
||||
return;
|
||||
}
|
||||
@ -6074,41 +6089,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function typeIdenticalToSomeType(source: Type, target: UnionOrIntersectionType): boolean {
|
||||
for (const t of target.types) {
|
||||
if (isTypeIdenticalTo(source, t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reduced form of the source type. This type is computed by by removing all source
|
||||
* constituents that have an identical match in the target type.
|
||||
*/
|
||||
function reduceUnionOrIntersectionType(source: UnionOrIntersectionType, target: UnionOrIntersectionType) {
|
||||
let sourceTypes = source.types;
|
||||
let sourceIndex = 0;
|
||||
let modified = false;
|
||||
while (sourceIndex < sourceTypes.length) {
|
||||
if (typeIdenticalToSomeType(sourceTypes[sourceIndex], target)) {
|
||||
if (!modified) {
|
||||
sourceTypes = sourceTypes.slice(0);
|
||||
modified = true;
|
||||
}
|
||||
sourceTypes.splice(sourceIndex, 1);
|
||||
}
|
||||
else {
|
||||
sourceIndex++;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
return source.flags & TypeFlags.Union ? getUnionType(sourceTypes, /*noSubtypeReduction*/ true) : getIntersectionType(sourceTypes);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
|
||||
let inferences = context.inferences[index];
|
||||
return inferences.primary || inferences.secondary || emptyArray;
|
||||
@ -7882,6 +7862,7 @@ namespace ts {
|
||||
return prop || unknownSymbol;
|
||||
}
|
||||
|
||||
let jsxElementClassType: Type = undefined;
|
||||
function getJsxGlobalElementClassType(): Type {
|
||||
if (!jsxElementClassType) {
|
||||
jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
//// [genericSignatureIdentity.ts]
|
||||
// This test is here to remind us of our current limits of type identity checking.
|
||||
// Ideally all of the below declarations would be considered different (and thus errors)
|
||||
// but they aren't because we erase type parameters to type any and don't check that
|
||||
// constraints are identical.
|
||||
|
||||
var x: {
|
||||
<T extends Date>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T extends number>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T>(x: any): any;
|
||||
};
|
||||
|
||||
|
||||
//// [genericSignatureIdentity.js]
|
||||
// This test is here to remind us of our current limits of type identity checking.
|
||||
// Ideally all of the below declarations would be considered different (and thus errors)
|
||||
// but they aren't because we erase type parameters to type any and don't check that
|
||||
// constraints are identical.
|
||||
var x;
|
||||
var x;
|
||||
var x;
|
||||
var x;
|
||||
@ -1,49 +0,0 @@
|
||||
=== tests/cases/compiler/genericSignatureIdentity.ts ===
|
||||
// This test is here to remind us of our current limits of type identity checking.
|
||||
// Ideally all of the below declarations would be considered different (and thus errors)
|
||||
// but they aren't because we erase type parameters to type any and don't check that
|
||||
// constraints are identical.
|
||||
|
||||
var x: {
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 5, 3), Decl(genericSignatureIdentity.ts, 9, 3), Decl(genericSignatureIdentity.ts, 13, 3), Decl(genericSignatureIdentity.ts, 17, 3))
|
||||
|
||||
<T extends Date>(x: T): T;
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 6, 5))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 6, 21))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 6, 5))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 6, 5))
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 5, 3), Decl(genericSignatureIdentity.ts, 9, 3), Decl(genericSignatureIdentity.ts, 13, 3), Decl(genericSignatureIdentity.ts, 17, 3))
|
||||
|
||||
<T extends number>(x: T): T;
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 10, 5))
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 10, 23))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 10, 5))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 10, 5))
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 5, 3), Decl(genericSignatureIdentity.ts, 9, 3), Decl(genericSignatureIdentity.ts, 13, 3), Decl(genericSignatureIdentity.ts, 17, 3))
|
||||
|
||||
<T>(x: T): T;
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 14, 5))
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 14, 8))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 14, 5))
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 14, 5))
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 5, 3), Decl(genericSignatureIdentity.ts, 9, 3), Decl(genericSignatureIdentity.ts, 13, 3), Decl(genericSignatureIdentity.ts, 17, 3))
|
||||
|
||||
<T>(x: any): any;
|
||||
>T : Symbol(T, Decl(genericSignatureIdentity.ts, 18, 5))
|
||||
>x : Symbol(x, Decl(genericSignatureIdentity.ts, 18, 8))
|
||||
|
||||
};
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
=== tests/cases/compiler/genericSignatureIdentity.ts ===
|
||||
// This test is here to remind us of our current limits of type identity checking.
|
||||
// Ideally all of the below declarations would be considered different (and thus errors)
|
||||
// but they aren't because we erase type parameters to type any and don't check that
|
||||
// constraints are identical.
|
||||
|
||||
var x: {
|
||||
>x : <T extends Date>(x: T) => T
|
||||
|
||||
<T extends Date>(x: T): T;
|
||||
>T : T
|
||||
>Date : Date
|
||||
>x : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : <T extends Date>(x: T) => T
|
||||
|
||||
<T extends number>(x: T): T;
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : <T extends Date>(x: T) => T
|
||||
|
||||
<T>(x: T): T;
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
};
|
||||
|
||||
var x: {
|
||||
>x : <T extends Date>(x: T) => T
|
||||
|
||||
<T>(x: any): any;
|
||||
>T : T
|
||||
>x : any
|
||||
|
||||
};
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
//// [unionAndIntersectionInference1.ts]
|
||||
// Repro from #2264
|
||||
|
||||
interface Y { 'i am a very certain type': Y }
|
||||
var y: Y = <Y>undefined;
|
||||
function destructure<a, r>(
|
||||
something: a | Y,
|
||||
haveValue: (value: a) => r,
|
||||
haveY: (value: Y) => r
|
||||
): r {
|
||||
return something === y ? haveY(y) : haveValue(<a>something);
|
||||
}
|
||||
|
||||
var value = Math.random() > 0.5 ? 'hey!' : <Y>undefined;
|
||||
|
||||
var result = destructure(value, text => 'string', y => 'other one'); // text: string, y: Y
|
||||
|
||||
// Repro from #4212
|
||||
|
||||
function isVoid<a>(value: void | a): value is void {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isNonVoid<a>(value: void | a) : value is a {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function foo1<a>(value: void|a): void {
|
||||
if (isVoid(value)) {
|
||||
value; // value is void
|
||||
} else {
|
||||
value; // value is a
|
||||
}
|
||||
}
|
||||
|
||||
function baz1<a>(value: void|a): void {
|
||||
if (isNonVoid(value)) {
|
||||
value; // value is a
|
||||
} else {
|
||||
value; // value is void
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #5417
|
||||
|
||||
type Maybe<T> = T | void;
|
||||
|
||||
function get<U>(x: U | void): U {
|
||||
return null; // just an example
|
||||
}
|
||||
|
||||
let foo: Maybe<string>;
|
||||
get(foo).toUpperCase(); // Ok
|
||||
|
||||
// Repro from #5456
|
||||
|
||||
interface Man {
|
||||
walks: boolean;
|
||||
}
|
||||
|
||||
interface Bear {
|
||||
roars: boolean;
|
||||
}
|
||||
|
||||
interface Pig {
|
||||
oinks: boolean;
|
||||
}
|
||||
|
||||
declare function pigify<T>(y: T & Bear): T & Pig;
|
||||
declare var mbp: Man & Bear;
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
|
||||
|
||||
//// [unionAndIntersectionInference1.js]
|
||||
// Repro from #2264
|
||||
var y = undefined;
|
||||
function destructure(something, haveValue, haveY) {
|
||||
return something === y ? haveY(y) : haveValue(something);
|
||||
}
|
||||
var value = Math.random() > 0.5 ? 'hey!' : undefined;
|
||||
var result = destructure(value, function (text) { return 'string'; }, function (y) { return 'other one'; }); // text: string, y: Y
|
||||
// Repro from #4212
|
||||
function isVoid(value) {
|
||||
return undefined;
|
||||
}
|
||||
function isNonVoid(value) {
|
||||
return undefined;
|
||||
}
|
||||
function foo1(value) {
|
||||
if (isVoid(value)) {
|
||||
value; // value is void
|
||||
}
|
||||
else {
|
||||
value; // value is a
|
||||
}
|
||||
}
|
||||
function baz1(value) {
|
||||
if (isNonVoid(value)) {
|
||||
value; // value is a
|
||||
}
|
||||
else {
|
||||
value; // value is void
|
||||
}
|
||||
}
|
||||
function get(x) {
|
||||
return null; // just an example
|
||||
}
|
||||
var foo;
|
||||
get(foo).toUpperCase(); // Ok
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
@ -1,202 +0,0 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference1.ts ===
|
||||
// Repro from #2264
|
||||
|
||||
interface Y { 'i am a very certain type': Y }
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
|
||||
var y: Y = <Y>undefined;
|
||||
>y : Symbol(y, Decl(unionAndIntersectionInference1.ts, 3, 3))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
function destructure<a, r>(
|
||||
>destructure : Symbol(destructure, Decl(unionAndIntersectionInference1.ts, 3, 24))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 4, 21))
|
||||
>r : Symbol(r, Decl(unionAndIntersectionInference1.ts, 4, 23))
|
||||
|
||||
something: a | Y,
|
||||
>something : Symbol(something, Decl(unionAndIntersectionInference1.ts, 4, 27))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 4, 21))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
|
||||
haveValue: (value: a) => r,
|
||||
>haveValue : Symbol(haveValue, Decl(unionAndIntersectionInference1.ts, 5, 21))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 6, 16))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 4, 21))
|
||||
>r : Symbol(r, Decl(unionAndIntersectionInference1.ts, 4, 23))
|
||||
|
||||
haveY: (value: Y) => r
|
||||
>haveY : Symbol(haveY, Decl(unionAndIntersectionInference1.ts, 6, 31))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 7, 12))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>r : Symbol(r, Decl(unionAndIntersectionInference1.ts, 4, 23))
|
||||
|
||||
): r {
|
||||
>r : Symbol(r, Decl(unionAndIntersectionInference1.ts, 4, 23))
|
||||
|
||||
return something === y ? haveY(y) : haveValue(<a>something);
|
||||
>something : Symbol(something, Decl(unionAndIntersectionInference1.ts, 4, 27))
|
||||
>y : Symbol(y, Decl(unionAndIntersectionInference1.ts, 3, 3))
|
||||
>haveY : Symbol(haveY, Decl(unionAndIntersectionInference1.ts, 6, 31))
|
||||
>y : Symbol(y, Decl(unionAndIntersectionInference1.ts, 3, 3))
|
||||
>haveValue : Symbol(haveValue, Decl(unionAndIntersectionInference1.ts, 5, 21))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 4, 21))
|
||||
>something : Symbol(something, Decl(unionAndIntersectionInference1.ts, 4, 27))
|
||||
}
|
||||
|
||||
var value = Math.random() > 0.5 ? 'hey!' : <Y>undefined;
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 12, 3))
|
||||
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
var result = destructure(value, text => 'string', y => 'other one'); // text: string, y: Y
|
||||
>result : Symbol(result, Decl(unionAndIntersectionInference1.ts, 14, 3))
|
||||
>destructure : Symbol(destructure, Decl(unionAndIntersectionInference1.ts, 3, 24))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 12, 3))
|
||||
>text : Symbol(text, Decl(unionAndIntersectionInference1.ts, 14, 31))
|
||||
>y : Symbol(y, Decl(unionAndIntersectionInference1.ts, 14, 49))
|
||||
|
||||
// Repro from #4212
|
||||
|
||||
function isVoid<a>(value: void | a): value is void {
|
||||
>isVoid : Symbol(isVoid, Decl(unionAndIntersectionInference1.ts, 14, 68))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 18, 16))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 18, 19))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 18, 16))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 18, 19))
|
||||
|
||||
return undefined;
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
|
||||
function isNonVoid<a>(value: void | a) : value is a {
|
||||
>isNonVoid : Symbol(isNonVoid, Decl(unionAndIntersectionInference1.ts, 20, 1))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 22, 19))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 22, 22))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 22, 19))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 22, 22))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 22, 19))
|
||||
|
||||
return undefined;
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
|
||||
function foo1<a>(value: void|a): void {
|
||||
>foo1 : Symbol(foo1, Decl(unionAndIntersectionInference1.ts, 24, 1))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 26, 14))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 26, 17))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 26, 14))
|
||||
|
||||
if (isVoid(value)) {
|
||||
>isVoid : Symbol(isVoid, Decl(unionAndIntersectionInference1.ts, 14, 68))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 26, 17))
|
||||
|
||||
value; // value is void
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 26, 17))
|
||||
|
||||
} else {
|
||||
value; // value is a
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 26, 17))
|
||||
}
|
||||
}
|
||||
|
||||
function baz1<a>(value: void|a): void {
|
||||
>baz1 : Symbol(baz1, Decl(unionAndIntersectionInference1.ts, 32, 1))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 34, 14))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 34, 17))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference1.ts, 34, 14))
|
||||
|
||||
if (isNonVoid(value)) {
|
||||
>isNonVoid : Symbol(isNonVoid, Decl(unionAndIntersectionInference1.ts, 20, 1))
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 34, 17))
|
||||
|
||||
value; // value is a
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 34, 17))
|
||||
|
||||
} else {
|
||||
value; // value is void
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 34, 17))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #5417
|
||||
|
||||
type Maybe<T> = T | void;
|
||||
>Maybe : Symbol(Maybe, Decl(unionAndIntersectionInference1.ts, 40, 1))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 44, 11))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 44, 11))
|
||||
|
||||
function get<U>(x: U | void): U {
|
||||
>get : Symbol(get, Decl(unionAndIntersectionInference1.ts, 44, 25))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 46, 13))
|
||||
>x : Symbol(x, Decl(unionAndIntersectionInference1.ts, 46, 16))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 46, 13))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 46, 13))
|
||||
|
||||
return null; // just an example
|
||||
}
|
||||
|
||||
let foo: Maybe<string>;
|
||||
>foo : Symbol(foo, Decl(unionAndIntersectionInference1.ts, 50, 3))
|
||||
>Maybe : Symbol(Maybe, Decl(unionAndIntersectionInference1.ts, 40, 1))
|
||||
|
||||
get(foo).toUpperCase(); // Ok
|
||||
>get(foo).toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --))
|
||||
>get : Symbol(get, Decl(unionAndIntersectionInference1.ts, 44, 25))
|
||||
>foo : Symbol(foo, Decl(unionAndIntersectionInference1.ts, 50, 3))
|
||||
>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --))
|
||||
|
||||
// Repro from #5456
|
||||
|
||||
interface Man {
|
||||
>Man : Symbol(Man, Decl(unionAndIntersectionInference1.ts, 51, 23))
|
||||
|
||||
walks: boolean;
|
||||
>walks : Symbol(walks, Decl(unionAndIntersectionInference1.ts, 55, 15))
|
||||
}
|
||||
|
||||
interface Bear {
|
||||
>Bear : Symbol(Bear, Decl(unionAndIntersectionInference1.ts, 57, 1))
|
||||
|
||||
roars: boolean;
|
||||
>roars : Symbol(roars, Decl(unionAndIntersectionInference1.ts, 59, 16))
|
||||
}
|
||||
|
||||
interface Pig {
|
||||
>Pig : Symbol(Pig, Decl(unionAndIntersectionInference1.ts, 61, 1))
|
||||
|
||||
oinks: boolean;
|
||||
>oinks : Symbol(oinks, Decl(unionAndIntersectionInference1.ts, 63, 15))
|
||||
}
|
||||
|
||||
declare function pigify<T>(y: T & Bear): T & Pig;
|
||||
>pigify : Symbol(pigify, Decl(unionAndIntersectionInference1.ts, 65, 1))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 67, 24))
|
||||
>y : Symbol(y, Decl(unionAndIntersectionInference1.ts, 67, 27))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 67, 24))
|
||||
>Bear : Symbol(Bear, Decl(unionAndIntersectionInference1.ts, 57, 1))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 67, 24))
|
||||
>Pig : Symbol(Pig, Decl(unionAndIntersectionInference1.ts, 61, 1))
|
||||
|
||||
declare var mbp: Man & Bear;
|
||||
>mbp : Symbol(mbp, Decl(unionAndIntersectionInference1.ts, 68, 11))
|
||||
>Man : Symbol(Man, Decl(unionAndIntersectionInference1.ts, 51, 23))
|
||||
>Bear : Symbol(Bear, Decl(unionAndIntersectionInference1.ts, 57, 1))
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
>pigify(mbp).oinks : Symbol(Pig.oinks, Decl(unionAndIntersectionInference1.ts, 63, 15))
|
||||
>pigify : Symbol(pigify, Decl(unionAndIntersectionInference1.ts, 65, 1))
|
||||
>mbp : Symbol(mbp, Decl(unionAndIntersectionInference1.ts, 68, 11))
|
||||
>oinks : Symbol(Pig.oinks, Decl(unionAndIntersectionInference1.ts, 63, 15))
|
||||
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
>pigify(mbp).walks : Symbol(Man.walks, Decl(unionAndIntersectionInference1.ts, 55, 15))
|
||||
>pigify : Symbol(pigify, Decl(unionAndIntersectionInference1.ts, 65, 1))
|
||||
>mbp : Symbol(mbp, Decl(unionAndIntersectionInference1.ts, 68, 11))
|
||||
>walks : Symbol(Man.walks, Decl(unionAndIntersectionInference1.ts, 55, 15))
|
||||
|
||||
@ -1,226 +0,0 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference1.ts ===
|
||||
// Repro from #2264
|
||||
|
||||
interface Y { 'i am a very certain type': Y }
|
||||
>Y : Y
|
||||
>Y : Y
|
||||
|
||||
var y: Y = <Y>undefined;
|
||||
>y : Y
|
||||
>Y : Y
|
||||
><Y>undefined : Y
|
||||
>Y : Y
|
||||
>undefined : undefined
|
||||
|
||||
function destructure<a, r>(
|
||||
>destructure : <a, r>(something: a | Y, haveValue: (value: a) => r, haveY: (value: Y) => r) => r
|
||||
>a : a
|
||||
>r : r
|
||||
|
||||
something: a | Y,
|
||||
>something : a | Y
|
||||
>a : a
|
||||
>Y : Y
|
||||
|
||||
haveValue: (value: a) => r,
|
||||
>haveValue : (value: a) => r
|
||||
>value : a
|
||||
>a : a
|
||||
>r : r
|
||||
|
||||
haveY: (value: Y) => r
|
||||
>haveY : (value: Y) => r
|
||||
>value : Y
|
||||
>Y : Y
|
||||
>r : r
|
||||
|
||||
): r {
|
||||
>r : r
|
||||
|
||||
return something === y ? haveY(y) : haveValue(<a>something);
|
||||
>something === y ? haveY(y) : haveValue(<a>something) : r
|
||||
>something === y : boolean
|
||||
>something : a | Y
|
||||
>y : Y
|
||||
>haveY(y) : r
|
||||
>haveY : (value: Y) => r
|
||||
>y : Y
|
||||
>haveValue(<a>something) : r
|
||||
>haveValue : (value: a) => r
|
||||
><a>something : a
|
||||
>a : a
|
||||
>something : a | Y
|
||||
}
|
||||
|
||||
var value = Math.random() > 0.5 ? 'hey!' : <Y>undefined;
|
||||
>value : string | Y
|
||||
>Math.random() > 0.5 ? 'hey!' : <Y>undefined : string | Y
|
||||
>Math.random() > 0.5 : boolean
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
>Math : Math
|
||||
>random : () => number
|
||||
>0.5 : number
|
||||
>'hey!' : string
|
||||
><Y>undefined : Y
|
||||
>Y : Y
|
||||
>undefined : undefined
|
||||
|
||||
var result = destructure(value, text => 'string', y => 'other one'); // text: string, y: Y
|
||||
>result : string
|
||||
>destructure(value, text => 'string', y => 'other one') : string
|
||||
>destructure : <a, r>(something: a | Y, haveValue: (value: a) => r, haveY: (value: Y) => r) => r
|
||||
>value : string | Y
|
||||
>text => 'string' : (text: string) => string
|
||||
>text : string
|
||||
>'string' : string
|
||||
>y => 'other one' : (y: Y) => string
|
||||
>y : Y
|
||||
>'other one' : string
|
||||
|
||||
// Repro from #4212
|
||||
|
||||
function isVoid<a>(value: void | a): value is void {
|
||||
>isVoid : <a>(value: void | a) => value is void
|
||||
>a : a
|
||||
>value : void | a
|
||||
>a : a
|
||||
>value : any
|
||||
|
||||
return undefined;
|
||||
>undefined : undefined
|
||||
}
|
||||
|
||||
function isNonVoid<a>(value: void | a) : value is a {
|
||||
>isNonVoid : <a>(value: void | a) => value is a
|
||||
>a : a
|
||||
>value : void | a
|
||||
>a : a
|
||||
>value : any
|
||||
>a : a
|
||||
|
||||
return undefined;
|
||||
>undefined : undefined
|
||||
}
|
||||
|
||||
function foo1<a>(value: void|a): void {
|
||||
>foo1 : <a>(value: void | a) => void
|
||||
>a : a
|
||||
>value : void | a
|
||||
>a : a
|
||||
|
||||
if (isVoid(value)) {
|
||||
>isVoid(value) : boolean
|
||||
>isVoid : <a>(value: void | a) => value is void
|
||||
>value : void | a
|
||||
|
||||
value; // value is void
|
||||
>value : void
|
||||
|
||||
} else {
|
||||
value; // value is a
|
||||
>value : a
|
||||
}
|
||||
}
|
||||
|
||||
function baz1<a>(value: void|a): void {
|
||||
>baz1 : <a>(value: void | a) => void
|
||||
>a : a
|
||||
>value : void | a
|
||||
>a : a
|
||||
|
||||
if (isNonVoid(value)) {
|
||||
>isNonVoid(value) : boolean
|
||||
>isNonVoid : <a>(value: void | a) => value is a
|
||||
>value : void | a
|
||||
|
||||
value; // value is a
|
||||
>value : a
|
||||
|
||||
} else {
|
||||
value; // value is void
|
||||
>value : void
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #5417
|
||||
|
||||
type Maybe<T> = T | void;
|
||||
>Maybe : T | void
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
function get<U>(x: U | void): U {
|
||||
>get : <U>(x: U | void) => U
|
||||
>U : U
|
||||
>x : U | void
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
return null; // just an example
|
||||
>null : null
|
||||
}
|
||||
|
||||
let foo: Maybe<string>;
|
||||
>foo : string | void
|
||||
>Maybe : T | void
|
||||
|
||||
get(foo).toUpperCase(); // Ok
|
||||
>get(foo).toUpperCase() : string
|
||||
>get(foo).toUpperCase : () => string
|
||||
>get(foo) : string
|
||||
>get : <U>(x: U | void) => U
|
||||
>foo : string | void
|
||||
>toUpperCase : () => string
|
||||
|
||||
// Repro from #5456
|
||||
|
||||
interface Man {
|
||||
>Man : Man
|
||||
|
||||
walks: boolean;
|
||||
>walks : boolean
|
||||
}
|
||||
|
||||
interface Bear {
|
||||
>Bear : Bear
|
||||
|
||||
roars: boolean;
|
||||
>roars : boolean
|
||||
}
|
||||
|
||||
interface Pig {
|
||||
>Pig : Pig
|
||||
|
||||
oinks: boolean;
|
||||
>oinks : boolean
|
||||
}
|
||||
|
||||
declare function pigify<T>(y: T & Bear): T & Pig;
|
||||
>pigify : <T>(y: T & Bear) => T & Pig
|
||||
>T : T
|
||||
>y : T & Bear
|
||||
>T : T
|
||||
>Bear : Bear
|
||||
>T : T
|
||||
>Pig : Pig
|
||||
|
||||
declare var mbp: Man & Bear;
|
||||
>mbp : Man & Bear
|
||||
>Man : Man
|
||||
>Bear : Bear
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
>pigify(mbp).oinks : boolean
|
||||
>pigify(mbp) : Man & Pig
|
||||
>pigify : <T>(y: T & Bear) => T & Pig
|
||||
>mbp : Man & Bear
|
||||
>oinks : boolean
|
||||
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
>pigify(mbp).walks : boolean
|
||||
>pigify(mbp) : Man & Pig
|
||||
>pigify : <T>(y: T & Bear) => T & Pig
|
||||
>mbp : Man & Bear
|
||||
>walks : boolean
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
//// [unionAndIntersectionInference2.ts]
|
||||
declare function f1<T>(x: T | string): T;
|
||||
|
||||
var a1: string;
|
||||
var b1: string | string[];
|
||||
var c1: string[] | string;
|
||||
var d1: string | { name: string };
|
||||
var e1: number | string | boolean;
|
||||
f1(a1); // string
|
||||
f1(b1); // string[]
|
||||
f1(c1); // string[]
|
||||
f1(d1); // { name: string }
|
||||
f1(e1); // number | boolean
|
||||
|
||||
declare function f2<T>(x: T & { name: string }): T;
|
||||
|
||||
var a2: string & { name: string };
|
||||
var b2: { name: string } & string[];
|
||||
var c2: string & { name: string } & number;
|
||||
var d2: string & { name: string } & number & { name: string };
|
||||
f2(a2); // string
|
||||
f2(b2); // string[]
|
||||
f2(c2); // string & number
|
||||
f2(d2); // string & number
|
||||
|
||||
|
||||
//// [unionAndIntersectionInference2.js]
|
||||
var a1;
|
||||
var b1;
|
||||
var c1;
|
||||
var d1;
|
||||
var e1;
|
||||
f1(a1); // string
|
||||
f1(b1); // string[]
|
||||
f1(c1); // string[]
|
||||
f1(d1); // { name: string }
|
||||
f1(e1); // number | boolean
|
||||
var a2;
|
||||
var b2;
|
||||
var c2;
|
||||
var d2;
|
||||
f2(a2); // string
|
||||
f2(b2); // string[]
|
||||
f2(c2); // string & number
|
||||
f2(d2); // string & number
|
||||
@ -1,85 +0,0 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts ===
|
||||
declare function f1<T>(x: T | string): T;
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 0, 20))
|
||||
>x : Symbol(x, Decl(unionAndIntersectionInference2.ts, 0, 23))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 0, 20))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 0, 20))
|
||||
|
||||
var a1: string;
|
||||
>a1 : Symbol(a1, Decl(unionAndIntersectionInference2.ts, 2, 3))
|
||||
|
||||
var b1: string | string[];
|
||||
>b1 : Symbol(b1, Decl(unionAndIntersectionInference2.ts, 3, 3))
|
||||
|
||||
var c1: string[] | string;
|
||||
>c1 : Symbol(c1, Decl(unionAndIntersectionInference2.ts, 4, 3))
|
||||
|
||||
var d1: string | { name: string };
|
||||
>d1 : Symbol(d1, Decl(unionAndIntersectionInference2.ts, 5, 3))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 5, 18))
|
||||
|
||||
var e1: number | string | boolean;
|
||||
>e1 : Symbol(e1, Decl(unionAndIntersectionInference2.ts, 6, 3))
|
||||
|
||||
f1(a1); // string
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>a1 : Symbol(a1, Decl(unionAndIntersectionInference2.ts, 2, 3))
|
||||
|
||||
f1(b1); // string[]
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>b1 : Symbol(b1, Decl(unionAndIntersectionInference2.ts, 3, 3))
|
||||
|
||||
f1(c1); // string[]
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>c1 : Symbol(c1, Decl(unionAndIntersectionInference2.ts, 4, 3))
|
||||
|
||||
f1(d1); // { name: string }
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>d1 : Symbol(d1, Decl(unionAndIntersectionInference2.ts, 5, 3))
|
||||
|
||||
f1(e1); // number | boolean
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference2.ts, 0, 0))
|
||||
>e1 : Symbol(e1, Decl(unionAndIntersectionInference2.ts, 6, 3))
|
||||
|
||||
declare function f2<T>(x: T & { name: string }): T;
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 13, 20))
|
||||
>x : Symbol(x, Decl(unionAndIntersectionInference2.ts, 13, 23))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 13, 20))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 13, 31))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference2.ts, 13, 20))
|
||||
|
||||
var a2: string & { name: string };
|
||||
>a2 : Symbol(a2, Decl(unionAndIntersectionInference2.ts, 15, 3))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 15, 18))
|
||||
|
||||
var b2: { name: string } & string[];
|
||||
>b2 : Symbol(b2, Decl(unionAndIntersectionInference2.ts, 16, 3))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 16, 9))
|
||||
|
||||
var c2: string & { name: string } & number;
|
||||
>c2 : Symbol(c2, Decl(unionAndIntersectionInference2.ts, 17, 3))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 17, 18))
|
||||
|
||||
var d2: string & { name: string } & number & { name: string };
|
||||
>d2 : Symbol(d2, Decl(unionAndIntersectionInference2.ts, 18, 3))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 18, 18))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference2.ts, 18, 46))
|
||||
|
||||
f2(a2); // string
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
|
||||
>a2 : Symbol(a2, Decl(unionAndIntersectionInference2.ts, 15, 3))
|
||||
|
||||
f2(b2); // string[]
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
|
||||
>b2 : Symbol(b2, Decl(unionAndIntersectionInference2.ts, 16, 3))
|
||||
|
||||
f2(c2); // string & number
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
|
||||
>c2 : Symbol(c2, Decl(unionAndIntersectionInference2.ts, 17, 3))
|
||||
|
||||
f2(d2); // string & number
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
|
||||
>d2 : Symbol(d2, Decl(unionAndIntersectionInference2.ts, 18, 3))
|
||||
|
||||
@ -1,94 +0,0 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference2.ts ===
|
||||
declare function f1<T>(x: T | string): T;
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>T : T
|
||||
>x : T | string
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
var a1: string;
|
||||
>a1 : string
|
||||
|
||||
var b1: string | string[];
|
||||
>b1 : string | string[]
|
||||
|
||||
var c1: string[] | string;
|
||||
>c1 : string[] | string
|
||||
|
||||
var d1: string | { name: string };
|
||||
>d1 : string | { name: string; }
|
||||
>name : string
|
||||
|
||||
var e1: number | string | boolean;
|
||||
>e1 : number | string | boolean
|
||||
|
||||
f1(a1); // string
|
||||
>f1(a1) : string
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>a1 : string
|
||||
|
||||
f1(b1); // string[]
|
||||
>f1(b1) : string[]
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>b1 : string | string[]
|
||||
|
||||
f1(c1); // string[]
|
||||
>f1(c1) : string[]
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>c1 : string[] | string
|
||||
|
||||
f1(d1); // { name: string }
|
||||
>f1(d1) : { name: string; }
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>d1 : string | { name: string; }
|
||||
|
||||
f1(e1); // number | boolean
|
||||
>f1(e1) : number | boolean
|
||||
>f1 : <T>(x: T | string) => T
|
||||
>e1 : number | string | boolean
|
||||
|
||||
declare function f2<T>(x: T & { name: string }): T;
|
||||
>f2 : <T>(x: T & { name: string; }) => T
|
||||
>T : T
|
||||
>x : T & { name: string; }
|
||||
>T : T
|
||||
>name : string
|
||||
>T : T
|
||||
|
||||
var a2: string & { name: string };
|
||||
>a2 : string & { name: string; }
|
||||
>name : string
|
||||
|
||||
var b2: { name: string } & string[];
|
||||
>b2 : { name: string; } & string[]
|
||||
>name : string
|
||||
|
||||
var c2: string & { name: string } & number;
|
||||
>c2 : string & { name: string; } & number
|
||||
>name : string
|
||||
|
||||
var d2: string & { name: string } & number & { name: string };
|
||||
>d2 : string & { name: string; } & number & { name: string; }
|
||||
>name : string
|
||||
>name : string
|
||||
|
||||
f2(a2); // string
|
||||
>f2(a2) : string
|
||||
>f2 : <T>(x: T & { name: string; }) => T
|
||||
>a2 : string & { name: string; }
|
||||
|
||||
f2(b2); // string[]
|
||||
>f2(b2) : string[]
|
||||
>f2 : <T>(x: T & { name: string; }) => T
|
||||
>b2 : { name: string; } & string[]
|
||||
|
||||
f2(c2); // string & number
|
||||
>f2(c2) : string & number
|
||||
>f2 : <T>(x: T & { name: string; }) => T
|
||||
>c2 : string & { name: string; } & number
|
||||
|
||||
f2(d2); // string & number
|
||||
>f2(d2) : string & number
|
||||
>f2 : <T>(x: T & { name: string; }) => T
|
||||
>d2 : string & { name: string; } & number & { name: string; }
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
//// [unionTypeParameterInference.ts]
|
||||
// Regression test for #5861
|
||||
|
||||
interface Foo<T> { prop: T; }
|
||||
|
||||
declare function lift<U>(value: U | Foo<U>): Foo<U>;
|
||||
|
||||
function unlift<U>(value: U | Foo<U>): U {
|
||||
return lift(value).prop;
|
||||
}
|
||||
|
||||
|
||||
//// [unionTypeParameterInference.js]
|
||||
// Regression test for #5861
|
||||
function unlift(value) {
|
||||
return lift(value).prop;
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
=== tests/cases/compiler/unionTypeParameterInference.ts ===
|
||||
// Regression test for #5861
|
||||
|
||||
interface Foo<T> { prop: T; }
|
||||
>Foo : Symbol(Foo, Decl(unionTypeParameterInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(unionTypeParameterInference.ts, 2, 14))
|
||||
>prop : Symbol(prop, Decl(unionTypeParameterInference.ts, 2, 18))
|
||||
>T : Symbol(T, Decl(unionTypeParameterInference.ts, 2, 14))
|
||||
|
||||
declare function lift<U>(value: U | Foo<U>): Foo<U>;
|
||||
>lift : Symbol(lift, Decl(unionTypeParameterInference.ts, 2, 29))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 4, 22))
|
||||
>value : Symbol(value, Decl(unionTypeParameterInference.ts, 4, 25))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 4, 22))
|
||||
>Foo : Symbol(Foo, Decl(unionTypeParameterInference.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 4, 22))
|
||||
>Foo : Symbol(Foo, Decl(unionTypeParameterInference.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 4, 22))
|
||||
|
||||
function unlift<U>(value: U | Foo<U>): U {
|
||||
>unlift : Symbol(unlift, Decl(unionTypeParameterInference.ts, 4, 52))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 6, 16))
|
||||
>value : Symbol(value, Decl(unionTypeParameterInference.ts, 6, 19))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 6, 16))
|
||||
>Foo : Symbol(Foo, Decl(unionTypeParameterInference.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 6, 16))
|
||||
>U : Symbol(U, Decl(unionTypeParameterInference.ts, 6, 16))
|
||||
|
||||
return lift(value).prop;
|
||||
>lift(value).prop : Symbol(Foo.prop, Decl(unionTypeParameterInference.ts, 2, 18))
|
||||
>lift : Symbol(lift, Decl(unionTypeParameterInference.ts, 2, 29))
|
||||
>value : Symbol(value, Decl(unionTypeParameterInference.ts, 6, 19))
|
||||
>prop : Symbol(Foo.prop, Decl(unionTypeParameterInference.ts, 2, 18))
|
||||
}
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
=== tests/cases/compiler/unionTypeParameterInference.ts ===
|
||||
// Regression test for #5861
|
||||
|
||||
interface Foo<T> { prop: T; }
|
||||
>Foo : Foo<T>
|
||||
>T : T
|
||||
>prop : T
|
||||
>T : T
|
||||
|
||||
declare function lift<U>(value: U | Foo<U>): Foo<U>;
|
||||
>lift : <U>(value: U | Foo<U>) => Foo<U>
|
||||
>U : U
|
||||
>value : U | Foo<U>
|
||||
>U : U
|
||||
>Foo : Foo<T>
|
||||
>U : U
|
||||
>Foo : Foo<T>
|
||||
>U : U
|
||||
|
||||
function unlift<U>(value: U | Foo<U>): U {
|
||||
>unlift : <U>(value: U | Foo<U>) => U
|
||||
>U : U
|
||||
>value : U | Foo<U>
|
||||
>U : U
|
||||
>Foo : Foo<T>
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
return lift(value).prop;
|
||||
>lift(value).prop : U
|
||||
>lift(value) : Foo<U>
|
||||
>lift : <U>(value: U | Foo<U>) => Foo<U>
|
||||
>value : U | Foo<U>
|
||||
>prop : U
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
// This test is here to remind us of our current limits of type identity checking.
|
||||
// Ideally all of the below declarations would be considered different (and thus errors)
|
||||
// but they aren't because we erase type parameters to type any and don't check that
|
||||
// constraints are identical.
|
||||
|
||||
var x: {
|
||||
<T extends Date>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T extends number>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T>(x: T): T;
|
||||
};
|
||||
|
||||
var x: {
|
||||
<T>(x: any): any;
|
||||
};
|
||||
@ -1,9 +0,0 @@
|
||||
// Regression test for #5861
|
||||
|
||||
interface Foo<T> { prop: T; }
|
||||
|
||||
declare function lift<U>(value: U | Foo<U>): Foo<U>;
|
||||
|
||||
function unlift<U>(value: U | Foo<U>): U {
|
||||
return lift(value).prop;
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
// Repro from #2264
|
||||
|
||||
interface Y { 'i am a very certain type': Y }
|
||||
var y: Y = <Y>undefined;
|
||||
function destructure<a, r>(
|
||||
something: a | Y,
|
||||
haveValue: (value: a) => r,
|
||||
haveY: (value: Y) => r
|
||||
): r {
|
||||
return something === y ? haveY(y) : haveValue(<a>something);
|
||||
}
|
||||
|
||||
var value = Math.random() > 0.5 ? 'hey!' : <Y>undefined;
|
||||
|
||||
var result = destructure(value, text => 'string', y => 'other one'); // text: string, y: Y
|
||||
|
||||
// Repro from #4212
|
||||
|
||||
function isVoid<a>(value: void | a): value is void {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isNonVoid<a>(value: void | a) : value is a {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function foo1<a>(value: void|a): void {
|
||||
if (isVoid(value)) {
|
||||
value; // value is void
|
||||
} else {
|
||||
value; // value is a
|
||||
}
|
||||
}
|
||||
|
||||
function baz1<a>(value: void|a): void {
|
||||
if (isNonVoid(value)) {
|
||||
value; // value is a
|
||||
} else {
|
||||
value; // value is void
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #5417
|
||||
|
||||
type Maybe<T> = T | void;
|
||||
|
||||
function get<U>(x: U | void): U {
|
||||
return null; // just an example
|
||||
}
|
||||
|
||||
let foo: Maybe<string>;
|
||||
get(foo).toUpperCase(); // Ok
|
||||
|
||||
// Repro from #5456
|
||||
|
||||
interface Man {
|
||||
walks: boolean;
|
||||
}
|
||||
|
||||
interface Bear {
|
||||
roars: boolean;
|
||||
}
|
||||
|
||||
interface Pig {
|
||||
oinks: boolean;
|
||||
}
|
||||
|
||||
declare function pigify<T>(y: T & Bear): T & Pig;
|
||||
declare var mbp: Man & Bear;
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
@ -1,23 +0,0 @@
|
||||
declare function f1<T>(x: T | string): T;
|
||||
|
||||
var a1: string;
|
||||
var b1: string | string[];
|
||||
var c1: string[] | string;
|
||||
var d1: string | { name: string };
|
||||
var e1: number | string | boolean;
|
||||
f1(a1); // string
|
||||
f1(b1); // string[]
|
||||
f1(c1); // string[]
|
||||
f1(d1); // { name: string }
|
||||
f1(e1); // number | boolean
|
||||
|
||||
declare function f2<T>(x: T & { name: string }): T;
|
||||
|
||||
var a2: string & { name: string };
|
||||
var b2: { name: string } & string[];
|
||||
var c2: string & { name: string } & number;
|
||||
var d2: string & { name: string } & number & { name: string };
|
||||
f2(a2); // string
|
||||
f2(b2); // string[]
|
||||
f2(c2); // string & number
|
||||
f2(d2); // string & number
|
||||
Loading…
x
Reference in New Issue
Block a user