merge with origin/master

This commit is contained in:
vladima 2015-12-17 21:30:47 -08:00
commit ae7d687a77
58 changed files with 2635 additions and 772 deletions

View file

@ -924,7 +924,8 @@ function lintFileAsync(options, path, cb) {
var lintTargets = compilerSources
.concat(harnessCoreSources)
.concat(serverCoreSources)
.concat(scriptSources);
.concat(scriptSources)
.concat([path.join(servicesDirectory, "services.ts")]);
desc("Runs tslint on the compiler sources");
task("lint", ["build-rules"], function() {

View file

@ -3507,7 +3507,7 @@ namespace ts {
function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreReturnTypes: boolean): Signature {
for (const s of signatureList) {
if (compareSignatures(s, signature, partialMatch, ignoreReturnTypes, compareTypes)) {
if (compareSignaturesIdentical(s, signature, partialMatch, ignoreReturnTypes, compareTypesIdentical)) {
return s;
}
}
@ -3768,11 +3768,14 @@ namespace ts {
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol {
const types = containingType.types;
let props: Symbol[];
// Flags we want to propagate to the result if they exist in all source symbols
let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None;
for (const current of types) {
const type = getApparentType(current);
if (type !== unknownType) {
const prop = getPropertyOfType(type, name);
if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) {
commonFlags &= prop.flags;
if (!props) {
props = [prop];
}
@ -3800,7 +3803,12 @@ namespace ts {
}
propTypes.push(getTypeOfSymbol(prop));
}
const result = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty, name);
const result = <TransientSymbol>createSymbol(
SymbolFlags.Property |
SymbolFlags.Transient |
SymbolFlags.SyntheticProperty |
commonFlags,
name);
result.containingType = containingType;
result.declarations = declarations;
result.type = containingType.flags & TypeFlags.Union ? getUnionType(propTypes) : getIntersectionType(propTypes);
@ -4959,7 +4967,7 @@ namespace ts {
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined);
}
function compareTypes(source: Type, target: Type): Ternary {
function compareTypesIdentical(source: Type, target: Type): Ternary {
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined) ? Ternary.True : Ternary.False;
}
@ -4979,10 +4987,96 @@ namespace ts {
return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain);
}
function isSignatureAssignableTo(source: Signature, target: Signature): boolean {
const sourceType = getOrCreateTypeFromSignature(source);
const targetType = getOrCreateTypeFromSignature(target);
return checkTypeRelatedTo(sourceType, targetType, assignableRelation, /*errorNode*/ undefined);
/**
* See signatureRelatedTo, compareSignaturesIdentical
*/
function isSignatureAssignableTo(source: Signature, target: Signature, ignoreReturnTypes: boolean): boolean {
// TODO (drosen): De-duplicate code between related functions.
if (source === target) {
return true;
}
if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) {
return 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);
const sourceMax = getNumNonRestParameters(source);
const targetMax = getNumNonRestParameters(target);
const checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax);
for (let i = 0; i < checkCount; i++) {
const s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source);
const t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target);
const related = isTypeAssignableTo(t, s) || isTypeAssignableTo(s, t);
if (!related) {
return false;
}
}
if (!ignoreReturnTypes) {
const targetReturnType = getReturnTypeOfSignature(target);
if (targetReturnType === voidType) {
return true;
}
const sourceReturnType = getReturnTypeOfSignature(source);
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) {
if (!(sourceReturnType.flags & TypeFlags.PredicateType)) {
return false;
}
}
return isTypeAssignableTo(sourceReturnType, targetReturnType);
}
return true;
}
function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean {
const erasedSource = getErasedSignature(implementation);
const erasedTarget = getErasedSignature(overload);
// First see if the return types are compatible in either direction.
const sourceReturnType = getReturnTypeOfSignature(erasedSource);
const targetReturnType = getReturnTypeOfSignature(erasedTarget);
if (targetReturnType === voidType
|| checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)
|| checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) {
return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
}
return false;
}
function getNumNonRestParameters(signature: Signature) {
const numParams = signature.parameters.length;
return signature.hasRestParameter ?
numParams - 1 :
numParams;
}
function getNumParametersToCheckForSignatureRelatability(source: Signature, sourceNonRestParamCount: number, target: Signature, targetNonRestParamCount: number) {
if (source.hasRestParameter === target.hasRestParameter) {
if (source.hasRestParameter) {
// If both have rest parameters, get the max and add 1 to
// compensate for the rest parameter.
return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1;
}
else {
return Math.min(sourceNonRestParamCount, targetNonRestParamCount);
}
}
else {
// Return the count for whichever signature doesn't have rest parameters.
return source.hasRestParameter ?
targetNonRestParamCount :
sourceNonRestParamCount;
}
}
/**
@ -5574,7 +5668,7 @@ namespace ts {
shouldElaborateErrors = false;
}
}
// don't elaborate the primitive apparent types (like Number)
// don't elaborate the primitive apparent types (like Number)
// because the actual primitives will have already been reported.
if (shouldElaborateErrors && !isPrimitiveApparentType(source)) {
reportError(Diagnostics.Type_0_provides_no_match_for_the_signature_1,
@ -5621,7 +5715,11 @@ namespace ts {
}
}
/**
* See signatureAssignableTo, signatureAssignableTo
*/
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
// TODO (drosen): De-duplicate code between related functions.
if (source === target) {
return Ternary.True;
}
@ -5673,10 +5771,12 @@ namespace ts {
}
const targetReturnType = getReturnTypeOfSignature(target);
if (targetReturnType === voidType) return result;
if (targetReturnType === voidType) {
return result;
}
const sourceReturnType = getReturnTypeOfSignature(source);
// The follow block preserves old behavior forbidding boolean returning functions from being assignable to type guard returning functions
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) {
if (!(sourceReturnType.flags & TypeFlags.PredicateType)) {
if (reportErrors) {
@ -5697,7 +5797,7 @@ namespace ts {
}
let result = Ternary.True;
for (let i = 0, len = sourceSignatures.length; i < len; ++i) {
const related = compareSignatures(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
if (!related) {
return Ternary.False;
}
@ -5830,7 +5930,7 @@ namespace ts {
}
function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean {
return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False;
return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== Ternary.False;
}
function compareProperties(sourceProp: Symbol, targetProp: Symbol, compareTypes: (source: Type, target: Type) => Ternary): Ternary {
@ -5877,7 +5977,11 @@ namespace ts {
return false;
}
function compareSignatures(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
/**
* See signatureRelatedTo, compareSignaturesIdentical
*/
function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
// TODO (drosen): De-duplicate code between related functions.
if (source === target) {
return Ternary.True;
}
@ -7605,7 +7709,7 @@ namespace ts {
// This signature will contribute to contextual union signature
signatureList = [signature];
}
else if (!compareSignatures(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypes)) {
else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
// Signatures aren't identical, do not use
return undefined;
}
@ -8280,9 +8384,9 @@ namespace ts {
// Props is of type 'any' or unknown
return links.resolvedJsxType = attributesType;
}
else if (!(attributesType.flags & TypeFlags.ObjectType)) {
// Props is not an object type
error(node.tagName, Diagnostics.JSX_element_attributes_type_0_must_be_an_object_type, typeToString(attributesType));
else if (attributesType.flags & TypeFlags.Union) {
// Props cannot be a union type
error(node.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType));
return links.resolvedJsxType = anyType;
}
else {
@ -11626,7 +11730,7 @@ namespace ts {
}
for (const otherSignature of signaturesToCheck) {
if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature)) {
if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature, /*ignoreReturnTypes*/ false)) {
return;
}
}
@ -11873,7 +11977,7 @@ namespace ts {
//
// The implementation is completely unrelated to the specialized signature, yet we do not check this.
for (const signature of signatures) {
if (!signature.hasStringLiterals && !isSignatureAssignableTo(bodySignature, signature)) {
if (!signature.hasStringLiterals && !isImplementationCompatibleWithOverload(bodySignature, signature)) {
error(signature.declaration, Diagnostics.Overload_signature_is_not_compatible_with_function_implementation);
break;
}

View file

@ -1691,7 +1691,7 @@
"category": "Error",
"code": 2528
},
"JSX element attributes type '{0}' must be an object type.": {
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
},

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
//// [conformanceFunctionOverloads.ts]
// Function overloads do not emit code
// Function overload signature with optional parameter
// Function overload signature with optional parameter
// Function overloads with generic and non-generic overloads
// Function overloads whose only difference is returning different unconstrained generic parameters
// Function overloads whose only difference is returning different constrained generic parameters
// Function overloads that differ only by type parameter constraints
// Function overloads with matching accessibility
// Function overloads with matching export
// Function overloads with more params than implementation signature
// Function overloads where return types are same infinitely recursive type reference
//// [conformanceFunctionOverloads.js]
// Function overloads do not emit code
// Function overload signature with optional parameter
// Function overload signature with optional parameter
// Function overloads with generic and non-generic overloads
// Function overloads whose only difference is returning different unconstrained generic parameters
// Function overloads whose only difference is returning different constrained generic parameters
// Function overloads that differ only by type parameter constraints
// Function overloads with matching accessibility
// Function overloads with matching export
// Function overloads with more params than implementation signature
// Function overloads where return types are same infinitely recursive type reference

View file

@ -1,25 +0,0 @@
=== tests/cases/conformance/functions/conformanceFunctionOverloads.ts ===
// Function overloads do not emit code
No type information for this code.
No type information for this code.// Function overload signature with optional parameter
No type information for this code.
No type information for this code.// Function overload signature with optional parameter
No type information for this code.
No type information for this code.// Function overloads with generic and non-generic overloads
No type information for this code.
No type information for this code.// Function overloads whose only difference is returning different unconstrained generic parameters
No type information for this code.
No type information for this code.// Function overloads whose only difference is returning different constrained generic parameters
No type information for this code.
No type information for this code.// Function overloads that differ only by type parameter constraints
No type information for this code.
No type information for this code.// Function overloads with matching accessibility
No type information for this code.
No type information for this code.// Function overloads with matching export
No type information for this code.
No type information for this code.// Function overloads with more params than implementation signature
No type information for this code.
No type information for this code.// Function overloads where return types are same infinitely recursive type reference
No type information for this code.
No type information for this code.
No type information for this code.

View file

@ -1,25 +0,0 @@
=== tests/cases/conformance/functions/conformanceFunctionOverloads.ts ===
// Function overloads do not emit code
No type information for this code.
No type information for this code.// Function overload signature with optional parameter
No type information for this code.
No type information for this code.// Function overload signature with optional parameter
No type information for this code.
No type information for this code.// Function overloads with generic and non-generic overloads
No type information for this code.
No type information for this code.// Function overloads whose only difference is returning different unconstrained generic parameters
No type information for this code.
No type information for this code.// Function overloads whose only difference is returning different constrained generic parameters
No type information for this code.
No type information for this code.// Function overloads that differ only by type parameter constraints
No type information for this code.
No type information for this code.// Function overloads with matching accessibility
No type information for this code.
No type information for this code.// Function overloads with matching export
No type information for this code.
No type information for this code.// Function overloads with more params than implementation signature
No type information for this code.
No type information for this code.// Function overloads where return types are same infinitely recursive type reference
No type information for this code.
No type information for this code.
No type information for this code.

View file

@ -0,0 +1,10 @@
tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts(1,10): error TS2394: Overload signature is not compatible with function implementation.
==== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts (1 errors) ====
function f(x: string): number;
~
!!! error TS2394: Overload signature is not compatible with function implementation.
function f(x: string): void {
return;
}

View file

@ -0,0 +1,10 @@
//// [functionOverloadCompatibilityWithVoid01.ts]
function f(x: string): number;
function f(x: string): void {
return;
}
//// [functionOverloadCompatibilityWithVoid01.js]
function f(x) {
return;
}

View file

@ -0,0 +1,10 @@
//// [functionOverloadCompatibilityWithVoid02.ts]
function f(x: string): void;
function f(x: string): number {
return 0;
}
//// [functionOverloadCompatibilityWithVoid02.js]
function f(x) {
return 0;
}

View file

@ -0,0 +1,11 @@
=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts ===
function f(x: string): void;
>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 28))
>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 11))
function f(x: string): number {
>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 28))
>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid02.ts, 1, 11))
return 0;
}

View file

@ -0,0 +1,12 @@
=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts ===
function f(x: string): void;
>f : (x: string) => void
>x : string
function f(x: string): number {
>f : (x: string) => void
>x : string
return 0;
>0 : number
}

View file

@ -0,0 +1,10 @@
//// [functionOverloadCompatibilityWithVoid03.ts]
function f(x: string): void;
function f(x: string): void {
return;
}
//// [functionOverloadCompatibilityWithVoid03.js]
function f(x) {
return;
}

View file

@ -0,0 +1,11 @@
=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts ===
function f(x: string): void;
>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 28))
>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 11))
function f(x: string): void {
>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 28))
>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid03.ts, 1, 11))
return;
}

View file

@ -0,0 +1,11 @@
=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts ===
function f(x: string): void;
>f : (x: string) => void
>x : string
function f(x: string): void {
>f : (x: string) => void
>x : string
return;
}

View file

@ -1,10 +0,0 @@
tests/cases/compiler/functionOverloads22.ts(2,10): error TS2394: Overload signature is not compatible with function implementation.
==== tests/cases/compiler/functionOverloads22.ts (1 errors) ====
function foo(bar:number):{a:number;}[];
function foo(bar:string):{a:number; b:string;}[];
~~~
!!! error TS2394: Overload signature is not compatible with function implementation.
function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] }

View file

@ -0,0 +1,19 @@
=== tests/cases/compiler/functionOverloads22.ts ===
function foo(bar:number):{a:number;}[];
>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49))
>bar : Symbol(bar, Decl(functionOverloads22.ts, 0, 13))
>a : Symbol(a, Decl(functionOverloads22.ts, 0, 26))
function foo(bar:string):{a:number; b:string;}[];
>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49))
>bar : Symbol(bar, Decl(functionOverloads22.ts, 1, 13))
>a : Symbol(a, Decl(functionOverloads22.ts, 1, 26))
>b : Symbol(b, Decl(functionOverloads22.ts, 1, 35))
function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] }
>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49))
>bar : Symbol(bar, Decl(functionOverloads22.ts, 2, 13))
>a : Symbol(a, Decl(functionOverloads22.ts, 2, 23))
>b : Symbol(b, Decl(functionOverloads22.ts, 2, 29))
>a : Symbol(a, Decl(functionOverloads22.ts, 2, 51))

View file

@ -0,0 +1,22 @@
=== tests/cases/compiler/functionOverloads22.ts ===
function foo(bar:number):{a:number;}[];
>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; }
>bar : number
>a : number
function foo(bar:string):{a:number; b:string;}[];
>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; }
>bar : string
>a : number
>b : string
function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] }
>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; }
>bar : any
>a : any
>b : any
>[{a:""}] : { a: string; }[]
>{a:""} : { a: string; }
>a : string
>"" : string

View file

@ -0,0 +1,24 @@
//// [functionOverloads43.ts]
function foo(bar: { a:number }[]): number;
function foo(bar: { a:string }[]): string;
function foo([x]: { a:number | string }[]): string | number {
if (x) {
return x.a;
}
return undefined;
}
var x = foo([{a: "str"}]);
var y = foo([{a: 100}]);
//// [functionOverloads43.js]
function foo(_a) {
var x = _a[0];
if (x) {
return x.a;
}
return undefined;
}
var x = foo([{ a: "str" }]);
var y = foo([{ a: 100 }]);

View file

@ -0,0 +1,39 @@
=== tests/cases/compiler/functionOverloads43.ts ===
function foo(bar: { a:number }[]): number;
>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42))
>bar : Symbol(bar, Decl(functionOverloads43.ts, 0, 13))
>a : Symbol(a, Decl(functionOverloads43.ts, 0, 19))
function foo(bar: { a:string }[]): string;
>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42))
>bar : Symbol(bar, Decl(functionOverloads43.ts, 1, 13))
>a : Symbol(a, Decl(functionOverloads43.ts, 1, 19))
function foo([x]: { a:number | string }[]): string | number {
>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42))
>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14))
>a : Symbol(a, Decl(functionOverloads43.ts, 2, 19))
if (x) {
>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14))
return x.a;
>x.a : Symbol(a, Decl(functionOverloads43.ts, 2, 19))
>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14))
>a : Symbol(a, Decl(functionOverloads43.ts, 2, 19))
}
return undefined;
>undefined : Symbol(undefined)
}
var x = foo([{a: "str"}]);
>x : Symbol(x, Decl(functionOverloads43.ts, 10, 3))
>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42))
>a : Symbol(a, Decl(functionOverloads43.ts, 10, 14))
var y = foo([{a: 100}]);
>y : Symbol(y, Decl(functionOverloads43.ts, 11, 3))
>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42))
>a : Symbol(a, Decl(functionOverloads43.ts, 11, 14))

View file

@ -0,0 +1,47 @@
=== tests/cases/compiler/functionOverloads43.ts ===
function foo(bar: { a:number }[]): number;
>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; }
>bar : { a: number; }[]
>a : number
function foo(bar: { a:string }[]): string;
>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; }
>bar : { a: string; }[]
>a : string
function foo([x]: { a:number | string }[]): string | number {
>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; }
>x : { a: number | string; }
>a : number | string
if (x) {
>x : { a: number | string; }
return x.a;
>x.a : number | string
>x : { a: number | string; }
>a : number | string
}
return undefined;
>undefined : undefined
}
var x = foo([{a: "str"}]);
>x : string
>foo([{a: "str"}]) : string
>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; }
>[{a: "str"}] : { a: string; }[]
>{a: "str"} : { a: string; }
>a : string
>"str" : string
var y = foo([{a: 100}]);
>y : number
>foo([{a: 100}]) : number
>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; }
>[{a: 100}] : { a: number; }[]
>{a: 100} : { a: number; }
>a : number
>100 : number

View file

@ -0,0 +1,37 @@
//// [functionOverloads44.ts]
interface Animal { animal }
interface Dog extends Animal { dog }
interface Cat extends Animal { cat }
function foo1(bar: { a:number }[]): Dog;
function foo1(bar: { a:string }[]): Animal;
function foo1([x]: { a:number | string }[]): Dog {
return undefined;
}
function foo2(bar: { a:number }[]): Cat;
function foo2(bar: { a:string }[]): Cat | Dog;
function foo2([x]: { a:number | string }[]): Cat {
return undefined;
}
var x1 = foo1([{a: "str"}]);
var y1 = foo1([{a: 100}]);
var x2 = foo2([{a: "str"}]);
var y2 = foo2([{a: 100}]);
//// [functionOverloads44.js]
function foo1(_a) {
var x = _a[0];
return undefined;
}
function foo2(_a) {
var x = _a[0];
return undefined;
}
var x1 = foo1([{ a: "str" }]);
var y1 = foo1([{ a: 100 }]);
var x2 = foo2([{ a: "str" }]);
var y2 = foo2([{ a: 100 }]);

View file

@ -0,0 +1,81 @@
=== tests/cases/compiler/functionOverloads44.ts ===
interface Animal { animal }
>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0))
>animal : Symbol(animal, Decl(functionOverloads44.ts, 0, 18))
interface Dog extends Animal { dog }
>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27))
>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0))
>dog : Symbol(dog, Decl(functionOverloads44.ts, 1, 30))
interface Cat extends Animal { cat }
>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36))
>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0))
>cat : Symbol(cat, Decl(functionOverloads44.ts, 2, 30))
function foo1(bar: { a:number }[]): Dog;
>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43))
>bar : Symbol(bar, Decl(functionOverloads44.ts, 4, 14))
>a : Symbol(a, Decl(functionOverloads44.ts, 4, 20))
>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27))
function foo1(bar: { a:string }[]): Animal;
>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43))
>bar : Symbol(bar, Decl(functionOverloads44.ts, 5, 14))
>a : Symbol(a, Decl(functionOverloads44.ts, 5, 20))
>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0))
function foo1([x]: { a:number | string }[]): Dog {
>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43))
>x : Symbol(x, Decl(functionOverloads44.ts, 6, 15))
>a : Symbol(a, Decl(functionOverloads44.ts, 6, 20))
>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27))
return undefined;
>undefined : Symbol(undefined)
}
function foo2(bar: { a:number }[]): Cat;
>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46))
>bar : Symbol(bar, Decl(functionOverloads44.ts, 10, 14))
>a : Symbol(a, Decl(functionOverloads44.ts, 10, 20))
>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36))
function foo2(bar: { a:string }[]): Cat | Dog;
>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46))
>bar : Symbol(bar, Decl(functionOverloads44.ts, 11, 14))
>a : Symbol(a, Decl(functionOverloads44.ts, 11, 20))
>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36))
>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27))
function foo2([x]: { a:number | string }[]): Cat {
>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46))
>x : Symbol(x, Decl(functionOverloads44.ts, 12, 15))
>a : Symbol(a, Decl(functionOverloads44.ts, 12, 20))
>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36))
return undefined;
>undefined : Symbol(undefined)
}
var x1 = foo1([{a: "str"}]);
>x1 : Symbol(x1, Decl(functionOverloads44.ts, 17, 3))
>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43))
>a : Symbol(a, Decl(functionOverloads44.ts, 17, 16))
var y1 = foo1([{a: 100}]);
>y1 : Symbol(y1, Decl(functionOverloads44.ts, 18, 3))
>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43))
>a : Symbol(a, Decl(functionOverloads44.ts, 18, 16))
var x2 = foo2([{a: "str"}]);
>x2 : Symbol(x2, Decl(functionOverloads44.ts, 20, 3))
>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46))
>a : Symbol(a, Decl(functionOverloads44.ts, 20, 16))
var y2 = foo2([{a: 100}]);
>y2 : Symbol(y2, Decl(functionOverloads44.ts, 21, 3))
>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46))
>a : Symbol(a, Decl(functionOverloads44.ts, 21, 16))

View file

@ -0,0 +1,97 @@
=== tests/cases/compiler/functionOverloads44.ts ===
interface Animal { animal }
>Animal : Animal
>animal : any
interface Dog extends Animal { dog }
>Dog : Dog
>Animal : Animal
>dog : any
interface Cat extends Animal { cat }
>Cat : Cat
>Animal : Animal
>cat : any
function foo1(bar: { a:number }[]): Dog;
>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; }
>bar : { a: number; }[]
>a : number
>Dog : Dog
function foo1(bar: { a:string }[]): Animal;
>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; }
>bar : { a: string; }[]
>a : string
>Animal : Animal
function foo1([x]: { a:number | string }[]): Dog {
>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; }
>x : { a: number | string; }
>a : number | string
>Dog : Dog
return undefined;
>undefined : undefined
}
function foo2(bar: { a:number }[]): Cat;
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; }
>bar : { a: number; }[]
>a : number
>Cat : Cat
function foo2(bar: { a:string }[]): Cat | Dog;
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; }
>bar : { a: string; }[]
>a : string
>Cat : Cat
>Dog : Dog
function foo2([x]: { a:number | string }[]): Cat {
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; }
>x : { a: number | string; }
>a : number | string
>Cat : Cat
return undefined;
>undefined : undefined
}
var x1 = foo1([{a: "str"}]);
>x1 : Animal
>foo1([{a: "str"}]) : Animal
>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; }
>[{a: "str"}] : { a: string; }[]
>{a: "str"} : { a: string; }
>a : string
>"str" : string
var y1 = foo1([{a: 100}]);
>y1 : Dog
>foo1([{a: 100}]) : Dog
>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; }
>[{a: 100}] : { a: number; }[]
>{a: 100} : { a: number; }
>a : number
>100 : number
var x2 = foo2([{a: "str"}]);
>x2 : Cat | Dog
>foo2([{a: "str"}]) : Cat | Dog
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; }
>[{a: "str"}] : { a: string; }[]
>{a: "str"} : { a: string; }
>a : string
>"str" : string
var y2 = foo2([{a: 100}]);
>y2 : Cat
>foo2([{a: 100}]) : Cat
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; }
>[{a: 100}] : { a: number; }[]
>{a: 100} : { a: number; }
>a : number
>100 : number

View file

@ -0,0 +1,37 @@
//// [functionOverloads45.ts]
interface Animal { animal }
interface Dog extends Animal { dog }
interface Cat extends Animal { cat }
function foo1(bar: { a:number }[]): Cat;
function foo1(bar: { a:string }[]): Dog;
function foo1([x]: { a:number | string }[]): Animal {
return undefined;
}
function foo2(bar: { a:number }[]): Cat;
function foo2(bar: { a:string }[]): Dog;
function foo2([x]: { a:number | string }[]): Cat | Dog {
return undefined;
}
var x1 = foo1([{a: "str"}]);
var y1 = foo1([{a: 100}]);
var x2 = foo2([{a: "str"}]);
var y2 = foo2([{a: 100}]);
//// [functionOverloads45.js]
function foo1(_a) {
var x = _a[0];
return undefined;
}
function foo2(_a) {
var x = _a[0];
return undefined;
}
var x1 = foo1([{ a: "str" }]);
var y1 = foo1([{ a: 100 }]);
var x2 = foo2([{ a: "str" }]);
var y2 = foo2([{ a: 100 }]);

View file

@ -0,0 +1,81 @@
=== tests/cases/compiler/functionOverloads45.ts ===
interface Animal { animal }
>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0))
>animal : Symbol(animal, Decl(functionOverloads45.ts, 0, 18))
interface Dog extends Animal { dog }
>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27))
>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0))
>dog : Symbol(dog, Decl(functionOverloads45.ts, 1, 30))
interface Cat extends Animal { cat }
>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36))
>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0))
>cat : Symbol(cat, Decl(functionOverloads45.ts, 2, 30))
function foo1(bar: { a:number }[]): Cat;
>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40))
>bar : Symbol(bar, Decl(functionOverloads45.ts, 4, 14))
>a : Symbol(a, Decl(functionOverloads45.ts, 4, 20))
>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36))
function foo1(bar: { a:string }[]): Dog;
>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40))
>bar : Symbol(bar, Decl(functionOverloads45.ts, 5, 14))
>a : Symbol(a, Decl(functionOverloads45.ts, 5, 20))
>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27))
function foo1([x]: { a:number | string }[]): Animal {
>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40))
>x : Symbol(x, Decl(functionOverloads45.ts, 6, 15))
>a : Symbol(a, Decl(functionOverloads45.ts, 6, 20))
>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0))
return undefined;
>undefined : Symbol(undefined)
}
function foo2(bar: { a:number }[]): Cat;
>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40))
>bar : Symbol(bar, Decl(functionOverloads45.ts, 10, 14))
>a : Symbol(a, Decl(functionOverloads45.ts, 10, 20))
>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36))
function foo2(bar: { a:string }[]): Dog;
>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40))
>bar : Symbol(bar, Decl(functionOverloads45.ts, 11, 14))
>a : Symbol(a, Decl(functionOverloads45.ts, 11, 20))
>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27))
function foo2([x]: { a:number | string }[]): Cat | Dog {
>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40))
>x : Symbol(x, Decl(functionOverloads45.ts, 12, 15))
>a : Symbol(a, Decl(functionOverloads45.ts, 12, 20))
>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36))
>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27))
return undefined;
>undefined : Symbol(undefined)
}
var x1 = foo1([{a: "str"}]);
>x1 : Symbol(x1, Decl(functionOverloads45.ts, 17, 3))
>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40))
>a : Symbol(a, Decl(functionOverloads45.ts, 17, 16))
var y1 = foo1([{a: 100}]);
>y1 : Symbol(y1, Decl(functionOverloads45.ts, 18, 3))
>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40))
>a : Symbol(a, Decl(functionOverloads45.ts, 18, 16))
var x2 = foo2([{a: "str"}]);
>x2 : Symbol(x2, Decl(functionOverloads45.ts, 20, 3))
>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40))
>a : Symbol(a, Decl(functionOverloads45.ts, 20, 16))
var y2 = foo2([{a: 100}]);
>y2 : Symbol(y2, Decl(functionOverloads45.ts, 21, 3))
>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40))
>a : Symbol(a, Decl(functionOverloads45.ts, 21, 16))

View file

@ -0,0 +1,97 @@
=== tests/cases/compiler/functionOverloads45.ts ===
interface Animal { animal }
>Animal : Animal
>animal : any
interface Dog extends Animal { dog }
>Dog : Dog
>Animal : Animal
>dog : any
interface Cat extends Animal { cat }
>Cat : Cat
>Animal : Animal
>cat : any
function foo1(bar: { a:number }[]): Cat;
>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>bar : { a: number; }[]
>a : number
>Cat : Cat
function foo1(bar: { a:string }[]): Dog;
>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>bar : { a: string; }[]
>a : string
>Dog : Dog
function foo1([x]: { a:number | string }[]): Animal {
>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>x : { a: number | string; }
>a : number | string
>Animal : Animal
return undefined;
>undefined : undefined
}
function foo2(bar: { a:number }[]): Cat;
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>bar : { a: number; }[]
>a : number
>Cat : Cat
function foo2(bar: { a:string }[]): Dog;
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>bar : { a: string; }[]
>a : string
>Dog : Dog
function foo2([x]: { a:number | string }[]): Cat | Dog {
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>x : { a: number | string; }
>a : number | string
>Cat : Cat
>Dog : Dog
return undefined;
>undefined : undefined
}
var x1 = foo1([{a: "str"}]);
>x1 : Dog
>foo1([{a: "str"}]) : Dog
>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>[{a: "str"}] : { a: string; }[]
>{a: "str"} : { a: string; }
>a : string
>"str" : string
var y1 = foo1([{a: 100}]);
>y1 : Cat
>foo1([{a: 100}]) : Cat
>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>[{a: 100}] : { a: number; }[]
>{a: 100} : { a: number; }
>a : number
>100 : number
var x2 = foo2([{a: "str"}]);
>x2 : Dog
>foo2([{a: "str"}]) : Dog
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>[{a: "str"}] : { a: string; }[]
>{a: "str"} : { a: string; }
>a : string
>"str" : string
var y2 = foo2([{a: 100}]);
>y2 : Cat
>foo2([{a: 100}]) : Cat
>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; }
>[{a: 100}] : { a: number; }[]
>{a: 100} : { a: number; }
>a : number
>100 : number

View file

@ -1,19 +0,0 @@
tests/cases/compiler/overloadOnConstConstraintChecks4.ts(9,10): error TS2394: Overload signature is not compatible with function implementation.
==== tests/cases/compiler/overloadOnConstConstraintChecks4.ts (1 errors) ====
class Z { }
class A extends Z { private x = 1 }
class B extends A {}
class C extends A {
public foo() { }
}
function foo(name: 'hi'): B;
function foo(name: 'bye'): C;
function foo(name: string): A; // error
~~~
!!! error TS2394: Overload signature is not compatible with function implementation.
function foo(name: any): Z {
return null;
}

View file

@ -7,7 +7,7 @@ class C extends A {
}
function foo(name: 'hi'): B;
function foo(name: 'bye'): C;
function foo(name: string): A; // error
function foo(name: string): A;
function foo(name: any): Z {
return null;
}

View file

@ -0,0 +1,43 @@
=== tests/cases/compiler/overloadOnConstConstraintChecks4.ts ===
class Z { }
>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0))
class A extends Z { private x = 1 }
>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11))
>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0))
>x : Symbol(x, Decl(overloadOnConstConstraintChecks4.ts, 1, 19))
class B extends A {}
>B : Symbol(B, Decl(overloadOnConstConstraintChecks4.ts, 1, 35))
>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11))
class C extends A {
>C : Symbol(C, Decl(overloadOnConstConstraintChecks4.ts, 2, 20))
>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11))
public foo() { }
>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 3, 19))
}
function foo(name: 'hi'): B;
>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30))
>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 6, 13))
>B : Symbol(B, Decl(overloadOnConstConstraintChecks4.ts, 1, 35))
function foo(name: 'bye'): C;
>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30))
>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 7, 13))
>C : Symbol(C, Decl(overloadOnConstConstraintChecks4.ts, 2, 20))
function foo(name: string): A;
>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30))
>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 8, 13))
>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11))
function foo(name: any): Z {
>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30))
>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 9, 13))
>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0))
return null;
}

View file

@ -0,0 +1,45 @@
=== tests/cases/compiler/overloadOnConstConstraintChecks4.ts ===
class Z { }
>Z : Z
class A extends Z { private x = 1 }
>A : A
>Z : Z
>x : number
>1 : number
class B extends A {}
>B : B
>A : A
class C extends A {
>C : C
>A : A
public foo() { }
>foo : () => void
}
function foo(name: 'hi'): B;
>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; }
>name : "hi"
>B : B
function foo(name: 'bye'): C;
>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; }
>name : "bye"
>C : C
function foo(name: string): A;
>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; }
>name : string
>A : A
function foo(name: any): Z {
>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; }
>name : any
>Z : Z
return null;
>null : null
}

View file

@ -20,7 +20,7 @@ function hasKind(entity: Entity, kind: "A"): entity is A;
function hasKind(entity: Entity, kind: "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is Entity;
function hasKind(entity: Entity, kind: Kind): boolean {
return kind === is;
return entity.kind === kind;
}
let x: A = {
@ -44,7 +44,7 @@ else {
//// [stringLiteralTypesAsTags01.js]
function hasKind(entity, kind) {
return kind === is;
return entity.kind === kind;
}
var x = {
kind: "A",

View file

@ -0,0 +1,112 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts ===
type Kind = "A" | "B"
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0))
interface Entity {
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
kind: Kind;
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18))
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0))
}
interface A extends Entity {
>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
kind: "A";
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 7, 28))
a: number;
>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 8, 14))
}
interface B extends Entity {
>B : Symbol(B, Decl(stringLiteralTypesAsTags01.ts, 10, 1))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
kind: "B";
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 12, 28))
b: string;
>b : Symbol(b, Decl(stringLiteralTypesAsTags01.ts, 13, 14))
}
function hasKind(entity: Entity, kind: "A"): entity is A;
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 17, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 17, 32))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 17, 17))
>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1))
function hasKind(entity: Entity, kind: "B"): entity is B;
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 18, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 18, 32))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 18, 17))
>B : Symbol(B, Decl(stringLiteralTypesAsTags01.ts, 10, 1))
function hasKind(entity: Entity, kind: Kind): entity is Entity;
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 19, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 19, 32))
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 19, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
function hasKind(entity: Entity, kind: Kind): boolean {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 20, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 20, 32))
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0))
return entity.kind === kind;
>entity.kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 20, 17))
>kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 20, 32))
}
let x: A = {
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1))
kind: "A",
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 24, 12))
a: 100,
>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 25, 14))
}
if (hasKind(x, "A")) {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
let a = x;
>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 30, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
}
else {
let b = x;
>b : Symbol(b, Decl(stringLiteralTypesAsTags01.ts, 33, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
}
if (!hasKind(x, "B")) {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
let c = x;
>c : Symbol(c, Decl(stringLiteralTypesAsTags01.ts, 37, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
}
else {
let d = x;
>d : Symbol(d, Decl(stringLiteralTypesAsTags01.ts, 40, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3))
}

View file

@ -0,0 +1,121 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts ===
type Kind = "A" | "B"
>Kind : "A" | "B"
interface Entity {
>Entity : Entity
kind: Kind;
>kind : "A" | "B"
>Kind : "A" | "B"
}
interface A extends Entity {
>A : A
>Entity : Entity
kind: "A";
>kind : "A"
a: number;
>a : number
}
interface B extends Entity {
>B : B
>Entity : Entity
kind: "B";
>kind : "B"
b: string;
>b : string
}
function hasKind(entity: Entity, kind: "A"): entity is A;
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>entity : Entity
>Entity : Entity
>kind : "A"
>entity : any
>A : A
function hasKind(entity: Entity, kind: "B"): entity is B;
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>entity : Entity
>Entity : Entity
>kind : "B"
>entity : any
>B : B
function hasKind(entity: Entity, kind: Kind): entity is Entity;
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>entity : Entity
>Entity : Entity
>kind : "A" | "B"
>Kind : "A" | "B"
>entity : any
>Entity : Entity
function hasKind(entity: Entity, kind: Kind): boolean {
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>entity : Entity
>Entity : Entity
>kind : "A" | "B"
>Kind : "A" | "B"
return entity.kind === kind;
>entity.kind === kind : boolean
>entity.kind : "A" | "B"
>entity : Entity
>kind : "A" | "B"
>kind : "A" | "B"
}
let x: A = {
>x : A
>A : A
>{ kind: "A", a: 100,} : { kind: "A"; a: number; }
kind: "A",
>kind : "A"
>"A" : "A"
a: 100,
>a : number
>100 : number
}
if (hasKind(x, "A")) {
>hasKind(x, "A") : entity is A
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>x : A
>"A" : "A"
let a = x;
>a : A
>x : A
}
else {
let b = x;
>b : A
>x : A
}
if (!hasKind(x, "B")) {
>!hasKind(x, "B") : boolean
>hasKind(x, "B") : entity is B
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; }
>x : A
>"B" : "B"
let c = x;
>c : A
>x : A
}
else {
let d = x;
>d : A
>x : A
}

View file

@ -1,8 +1,8 @@
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(20,10): error TS2394: Overload signature is not compatible with function implementation.
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(22,21): error TS2304: Cannot find name 'is'.
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts(18,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts(19,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts (2 errors) ====
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts (2 errors) ====
type Kind = "A" | "B"
@ -21,14 +21,13 @@ tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(22,21)
}
function hasKind(entity: Entity, kind: "A"): entity is A;
function hasKind(entity: Entity, kind: "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is Entity;
~~~~~~~
!!! error TS2394: Overload signature is not compatible with function implementation.
function hasKind(entity: Entity, kind: Kind): boolean {
return kind === is;
~~
!!! error TS2304: Cannot find name 'is'.
!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
function hasKind(entity: Entity, kind: "B"): entity is B;
~~~~~~~
!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
function hasKind(entity: Entity, kind: Kind): entity is (A | B) {
return entity.kind === kind;
}
let x: A = {

View file

@ -0,0 +1,81 @@
//// [stringLiteralTypesAsTags02.ts]
type Kind = "A" | "B"
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
function hasKind(entity: Entity, kind: "A"): entity is A;
function hasKind(entity: Entity, kind: "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is (A | B) {
return entity.kind === kind;
}
let x: A = {
kind: "A",
a: 100,
}
if (hasKind(x, "A")) {
let a = x;
}
else {
let b = x;
}
if (!hasKind(x, "B")) {
let c = x;
}
else {
let d = x;
}
//// [stringLiteralTypesAsTags02.js]
function hasKind(entity, kind) {
return entity.kind === kind;
}
var x = {
kind: "A",
a: 100
};
if (hasKind(x, "A")) {
var a = x;
}
else {
var b = x;
}
if (!hasKind(x, "B")) {
var c = x;
}
else {
var d = x;
}
//// [stringLiteralTypesAsTags02.d.ts]
declare type Kind = "A" | "B";
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
declare function hasKind(entity: Entity, kind: "A"): entity is A;
declare function hasKind(entity: Entity, kind: "B"): entity is B;
declare let x: A;

View file

@ -0,0 +1,85 @@
//// [stringLiteralTypesAsTags03.ts]
type Kind = "A" | "B"
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid
// interpreting respective overloads as "specialized" signatures.
// That way, we can avoid the need to look for a compatible overload
// signature and simply check compatibility with the implementation.
function hasKind(entity: Entity, kind: "A" | "A"): entity is A;
function hasKind(entity: Entity, kind: "B" | "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is Entity {
return entity.kind === kind;
}
let x: A = {
kind: "A",
a: 100,
}
if (hasKind(x, "A")) {
let a = x;
}
else {
let b = x;
}
if (!hasKind(x, "B")) {
let c = x;
}
else {
let d = x;
}
//// [stringLiteralTypesAsTags03.js]
function hasKind(entity, kind) {
return entity.kind === kind;
}
var x = {
kind: "A",
a: 100
};
if (hasKind(x, "A")) {
var a = x;
}
else {
var b = x;
}
if (!hasKind(x, "B")) {
var c = x;
}
else {
var d = x;
}
//// [stringLiteralTypesAsTags03.d.ts]
declare type Kind = "A" | "B";
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
declare function hasKind(entity: Entity, kind: "A" | "A"): entity is A;
declare function hasKind(entity: Entity, kind: "B" | "B"): entity is B;
declare let x: A;

View file

@ -0,0 +1,109 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts ===
type Kind = "A" | "B"
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0))
interface Entity {
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
kind: Kind;
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18))
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0))
}
interface A extends Entity {
>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
kind: "A";
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 7, 28))
a: number;
>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 8, 14))
}
interface B extends Entity {
>B : Symbol(B, Decl(stringLiteralTypesAsTags03.ts, 10, 1))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
kind: "B";
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 12, 28))
b: string;
>b : Symbol(b, Decl(stringLiteralTypesAsTags03.ts, 13, 14))
}
// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid
// interpreting respective overloads as "specialized" signatures.
// That way, we can avoid the need to look for a compatible overload
// signature and simply check compatibility with the implementation.
function hasKind(entity: Entity, kind: "A" | "A"): entity is A;
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 21, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 21, 32))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 21, 17))
>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1))
function hasKind(entity: Entity, kind: "B" | "B"): entity is B;
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 22, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 22, 32))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 22, 17))
>B : Symbol(B, Decl(stringLiteralTypesAsTags03.ts, 10, 1))
function hasKind(entity: Entity, kind: Kind): entity is Entity {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 23, 32))
>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17))
>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21))
return entity.kind === kind;
>entity.kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18))
>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17))
>kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18))
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 23, 32))
}
let x: A = {
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1))
kind: "A",
>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 27, 12))
a: 100,
>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 28, 14))
}
if (hasKind(x, "A")) {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
let a = x;
>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 33, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
}
else {
let b = x;
>b : Symbol(b, Decl(stringLiteralTypesAsTags03.ts, 36, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
}
if (!hasKind(x, "B")) {
>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
let c = x;
>c : Symbol(c, Decl(stringLiteralTypesAsTags03.ts, 40, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
}
else {
let d = x;
>d : Symbol(d, Decl(stringLiteralTypesAsTags03.ts, 43, 7))
>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3))
}

View file

@ -0,0 +1,118 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts ===
type Kind = "A" | "B"
>Kind : "A" | "B"
interface Entity {
>Entity : Entity
kind: Kind;
>kind : "A" | "B"
>Kind : "A" | "B"
}
interface A extends Entity {
>A : A
>Entity : Entity
kind: "A";
>kind : "A"
a: number;
>a : number
}
interface B extends Entity {
>B : B
>Entity : Entity
kind: "B";
>kind : "B"
b: string;
>b : string
}
// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid
// interpreting respective overloads as "specialized" signatures.
// That way, we can avoid the need to look for a compatible overload
// signature and simply check compatibility with the implementation.
function hasKind(entity: Entity, kind: "A" | "A"): entity is A;
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; }
>entity : Entity
>Entity : Entity
>kind : "A"
>entity : any
>A : A
function hasKind(entity: Entity, kind: "B" | "B"): entity is B;
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; }
>entity : Entity
>Entity : Entity
>kind : "B"
>entity : any
>B : B
function hasKind(entity: Entity, kind: Kind): entity is Entity {
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; }
>entity : Entity
>Entity : Entity
>kind : "A" | "B"
>Kind : "A" | "B"
>entity : any
>Entity : Entity
return entity.kind === kind;
>entity.kind === kind : boolean
>entity.kind : "A" | "B"
>entity : Entity
>kind : "A" | "B"
>kind : "A" | "B"
}
let x: A = {
>x : A
>A : A
>{ kind: "A", a: 100,} : { kind: "A"; a: number; }
kind: "A",
>kind : "A"
>"A" : "A"
a: 100,
>a : number
>100 : number
}
if (hasKind(x, "A")) {
>hasKind(x, "A") : entity is A
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; }
>x : A
>"A" : "A"
let a = x;
>a : A
>x : A
}
else {
let b = x;
>b : A
>x : A
}
if (!hasKind(x, "B")) {
>!hasKind(x, "B") : boolean
>hasKind(x, "B") : entity is B
>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; }
>x : A
>"B" : "B"
let c = x;
>c : A
>x : A
}
else {
let d = x;
>d : A
>x : A
}

View file

@ -1,59 +0,0 @@
tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts(11,10): error TS2354: No best common type exists among return expressions.
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts (1 errors) ====
type PrimitiveName = 'string' | 'number' | 'boolean';
function getFalsyPrimitive(x: "string"): string;
function getFalsyPrimitive(x: "number"): number;
function getFalsyPrimitive(x: "boolean"): boolean;
function getFalsyPrimitive(x: "boolean" | "string"): boolean | string;
function getFalsyPrimitive(x: "boolean" | "number"): boolean | number;
function getFalsyPrimitive(x: "number" | "string"): number | string;
function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
function getFalsyPrimitive(x: PrimitiveName) {
~~~~~~~~~~~~~~~~~
!!! error TS2354: No best common type exists among return expressions.
if (x === "string") {
return "";
}
if (x === "number") {
return 0;
}
if (x === "boolean") {
return false;
}
// Should be unreachable.
throw "Invalid value";
}
namespace Consts1 {
const EMPTY_STRING = getFalsyPrimitive("string");
const ZERO = getFalsyPrimitive('number');
const FALSE = getFalsyPrimitive("boolean");
}
const string: "string" = "string"
const number: "number" = "number"
const boolean: "boolean" = "boolean"
const stringOrNumber = string || number;
const stringOrBoolean = string || boolean;
const booleanOrNumber = number || boolean;
const stringOrBooleanOrNumber = stringOrBoolean || number;
namespace Consts2 {
const EMPTY_STRING = getFalsyPrimitive(string);
const ZERO = getFalsyPrimitive(number);
const FALSE = getFalsyPrimitive(boolean);
const a = getFalsyPrimitive(stringOrNumber);
const b = getFalsyPrimitive(stringOrBoolean);
const c = getFalsyPrimitive(booleanOrNumber);
const d = getFalsyPrimitive(stringOrBooleanOrNumber);
}

View file

@ -9,7 +9,7 @@ function getFalsyPrimitive(x: "boolean" | "string"): boolean | string;
function getFalsyPrimitive(x: "boolean" | "number"): boolean | number;
function getFalsyPrimitive(x: "number" | "string"): number | string;
function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
function getFalsyPrimitive(x: PrimitiveName) {
function getFalsyPrimitive(x: PrimitiveName): number | string | boolean {
if (x === "string") {
return "";
}

View file

@ -0,0 +1,144 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts ===
type PrimitiveName = 'string' | 'number' | 'boolean';
>PrimitiveName : Symbol(PrimitiveName, Decl(stringLiteralTypesOverloads01.ts, 0, 0))
function getFalsyPrimitive(x: "string"): string;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 3, 27))
function getFalsyPrimitive(x: "number"): number;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 4, 27))
function getFalsyPrimitive(x: "boolean"): boolean;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 5, 27))
function getFalsyPrimitive(x: "boolean" | "string"): boolean | string;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 6, 27))
function getFalsyPrimitive(x: "boolean" | "number"): boolean | number;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 7, 27))
function getFalsyPrimitive(x: "number" | "string"): number | string;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 8, 27))
function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 9, 27))
function getFalsyPrimitive(x: PrimitiveName): number | string | boolean {
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27))
>PrimitiveName : Symbol(PrimitiveName, Decl(stringLiteralTypesOverloads01.ts, 0, 0))
if (x === "string") {
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27))
return "";
}
if (x === "number") {
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27))
return 0;
}
if (x === "boolean") {
>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27))
return false;
}
// Should be unreachable.
throw "Invalid value";
}
namespace Consts1 {
>Consts1 : Symbol(Consts1, Decl(stringLiteralTypesOverloads01.ts, 23, 1))
const EMPTY_STRING = getFalsyPrimitive("string");
>EMPTY_STRING : Symbol(EMPTY_STRING, Decl(stringLiteralTypesOverloads01.ts, 26, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
const ZERO = getFalsyPrimitive('number');
>ZERO : Symbol(ZERO, Decl(stringLiteralTypesOverloads01.ts, 27, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
const FALSE = getFalsyPrimitive("boolean");
>FALSE : Symbol(FALSE, Decl(stringLiteralTypesOverloads01.ts, 28, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
}
const string: "string" = "string"
>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5))
const number: "number" = "number"
>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5))
const boolean: "boolean" = "boolean"
>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5))
const stringOrNumber = string || number;
>stringOrNumber : Symbol(stringOrNumber, Decl(stringLiteralTypesOverloads01.ts, 35, 5))
>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5))
>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5))
const stringOrBoolean = string || boolean;
>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5))
>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5))
>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5))
const booleanOrNumber = number || boolean;
>booleanOrNumber : Symbol(booleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 37, 5))
>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5))
>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5))
const stringOrBooleanOrNumber = stringOrBoolean || number;
>stringOrBooleanOrNumber : Symbol(stringOrBooleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 38, 5))
>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5))
>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5))
namespace Consts2 {
>Consts2 : Symbol(Consts2, Decl(stringLiteralTypesOverloads01.ts, 38, 58))
const EMPTY_STRING = getFalsyPrimitive(string);
>EMPTY_STRING : Symbol(EMPTY_STRING, Decl(stringLiteralTypesOverloads01.ts, 41, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5))
const ZERO = getFalsyPrimitive(number);
>ZERO : Symbol(ZERO, Decl(stringLiteralTypesOverloads01.ts, 42, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5))
const FALSE = getFalsyPrimitive(boolean);
>FALSE : Symbol(FALSE, Decl(stringLiteralTypesOverloads01.ts, 43, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5))
const a = getFalsyPrimitive(stringOrNumber);
>a : Symbol(a, Decl(stringLiteralTypesOverloads01.ts, 45, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>stringOrNumber : Symbol(stringOrNumber, Decl(stringLiteralTypesOverloads01.ts, 35, 5))
const b = getFalsyPrimitive(stringOrBoolean);
>b : Symbol(b, Decl(stringLiteralTypesOverloads01.ts, 46, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5))
const c = getFalsyPrimitive(booleanOrNumber);
>c : Symbol(c, Decl(stringLiteralTypesOverloads01.ts, 47, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>booleanOrNumber : Symbol(booleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 37, 5))
const d = getFalsyPrimitive(stringOrBooleanOrNumber);
>d : Symbol(d, Decl(stringLiteralTypesOverloads01.ts, 48, 9))
>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90))
>stringOrBooleanOrNumber : Symbol(stringOrBooleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 38, 5))
}

View file

@ -0,0 +1,174 @@
=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts ===
type PrimitiveName = 'string' | 'number' | 'boolean';
>PrimitiveName : "string" | "number" | "boolean"
function getFalsyPrimitive(x: "string"): string;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "string"
function getFalsyPrimitive(x: "number"): number;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "number"
function getFalsyPrimitive(x: "boolean"): boolean;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "boolean"
function getFalsyPrimitive(x: "boolean" | "string"): boolean | string;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "boolean" | "string"
function getFalsyPrimitive(x: "boolean" | "number"): boolean | number;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "boolean" | "number"
function getFalsyPrimitive(x: "number" | "string"): number | string;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "number" | "string"
function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "number" | "string" | "boolean"
function getFalsyPrimitive(x: PrimitiveName): number | string | boolean {
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>x : "string" | "number" | "boolean"
>PrimitiveName : "string" | "number" | "boolean"
if (x === "string") {
>x === "string" : boolean
>x : "string" | "number" | "boolean"
>"string" : string
return "";
>"" : string
}
if (x === "number") {
>x === "number" : boolean
>x : "string" | "number" | "boolean"
>"number" : string
return 0;
>0 : number
}
if (x === "boolean") {
>x === "boolean" : boolean
>x : "string" | "number" | "boolean"
>"boolean" : string
return false;
>false : boolean
}
// Should be unreachable.
throw "Invalid value";
>"Invalid value" : string
}
namespace Consts1 {
>Consts1 : typeof Consts1
const EMPTY_STRING = getFalsyPrimitive("string");
>EMPTY_STRING : string
>getFalsyPrimitive("string") : string
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>"string" : "string"
const ZERO = getFalsyPrimitive('number');
>ZERO : number
>getFalsyPrimitive('number') : number
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>'number' : "number"
const FALSE = getFalsyPrimitive("boolean");
>FALSE : boolean
>getFalsyPrimitive("boolean") : boolean
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>"boolean" : "boolean"
}
const string: "string" = "string"
>string : "string"
>"string" : "string"
const number: "number" = "number"
>number : "number"
>"number" : "number"
const boolean: "boolean" = "boolean"
>boolean : "boolean"
>"boolean" : "boolean"
const stringOrNumber = string || number;
>stringOrNumber : "string" | "number"
>string || number : "string" | "number"
>string : "string"
>number : "number"
const stringOrBoolean = string || boolean;
>stringOrBoolean : "string" | "boolean"
>string || boolean : "string" | "boolean"
>string : "string"
>boolean : "boolean"
const booleanOrNumber = number || boolean;
>booleanOrNumber : "number" | "boolean"
>number || boolean : "number" | "boolean"
>number : "number"
>boolean : "boolean"
const stringOrBooleanOrNumber = stringOrBoolean || number;
>stringOrBooleanOrNumber : "string" | "boolean" | "number"
>stringOrBoolean || number : "string" | "boolean" | "number"
>stringOrBoolean : "string" | "boolean"
>number : "number"
namespace Consts2 {
>Consts2 : typeof Consts2
const EMPTY_STRING = getFalsyPrimitive(string);
>EMPTY_STRING : string
>getFalsyPrimitive(string) : string
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>string : "string"
const ZERO = getFalsyPrimitive(number);
>ZERO : number
>getFalsyPrimitive(number) : number
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>number : "number"
const FALSE = getFalsyPrimitive(boolean);
>FALSE : boolean
>getFalsyPrimitive(boolean) : boolean
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>boolean : "boolean"
const a = getFalsyPrimitive(stringOrNumber);
>a : number | string
>getFalsyPrimitive(stringOrNumber) : number | string
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>stringOrNumber : "string" | "number"
const b = getFalsyPrimitive(stringOrBoolean);
>b : boolean | string
>getFalsyPrimitive(stringOrBoolean) : boolean | string
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>stringOrBoolean : "string" | "boolean"
const c = getFalsyPrimitive(booleanOrNumber);
>c : boolean | number
>getFalsyPrimitive(booleanOrNumber) : boolean | number
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>booleanOrNumber : "number" | "boolean"
const d = getFalsyPrimitive(stringOrBooleanOrNumber);
>d : number | string | boolean
>getFalsyPrimitive(stringOrBooleanOrNumber) : number | string | boolean
>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; }
>stringOrBooleanOrNumber : "string" | "boolean" | "number"
}

View file

@ -0,0 +1,33 @@
tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
interface IntrinsicAttributes {
ref?: string;
}
}
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
class MyComponent {
render() {
}
props: {
ref?: string;
}
}
// Should be an OK
var x = <MyComponent bar='world' />;
~~~
!!! error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.

View file

@ -0,0 +1,41 @@
//// [tests/cases/conformance/jsx/tsxAttributeResolution11.tsx] ////
//// [react.d.ts]
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
interface IntrinsicAttributes {
ref?: string;
}
}
//// [file.tsx]
class MyComponent {
render() {
}
props: {
ref?: string;
}
}
// Should be an OK
var x = <MyComponent bar='world' />;
//// [file.jsx]
var MyComponent = (function () {
function MyComponent() {
}
MyComponent.prototype.render = function () {
};
return MyComponent;
}());
// Should be an OK
var x = <MyComponent bar='world'/>;

View file

@ -0,0 +1,12 @@
function foo(bar: { a:number }[]): number;
function foo(bar: { a:string }[]): string;
function foo([x]: { a:number | string }[]): string | number {
if (x) {
return x.a;
}
return undefined;
}
var x = foo([{a: "str"}]);
var y = foo([{a: 100}]);

View file

@ -0,0 +1,22 @@
interface Animal { animal }
interface Dog extends Animal { dog }
interface Cat extends Animal { cat }
function foo1(bar: { a:number }[]): Dog;
function foo1(bar: { a:string }[]): Animal;
function foo1([x]: { a:number | string }[]): Dog {
return undefined;
}
function foo2(bar: { a:number }[]): Cat;
function foo2(bar: { a:string }[]): Cat | Dog;
function foo2([x]: { a:number | string }[]): Cat {
return undefined;
}
var x1 = foo1([{a: "str"}]);
var y1 = foo1([{a: 100}]);
var x2 = foo2([{a: "str"}]);
var y2 = foo2([{a: 100}]);

View file

@ -0,0 +1,22 @@
interface Animal { animal }
interface Dog extends Animal { dog }
interface Cat extends Animal { cat }
function foo1(bar: { a:number }[]): Cat;
function foo1(bar: { a:string }[]): Dog;
function foo1([x]: { a:number | string }[]): Animal {
return undefined;
}
function foo2(bar: { a:number }[]): Cat;
function foo2(bar: { a:string }[]): Dog;
function foo2([x]: { a:number | string }[]): Cat | Dog {
return undefined;
}
var x1 = foo1([{a: "str"}]);
var y1 = foo1([{a: 100}]);
var x2 = foo2([{a: "str"}]);
var y2 = foo2([{a: 100}]);

View file

@ -6,7 +6,7 @@ class C extends A {
}
function foo(name: 'hi'): B;
function foo(name: 'bye'): C;
function foo(name: string): A; // error
function foo(name: string): A;
function foo(name: any): Z {
return null;
}

View file

@ -1,22 +0,0 @@
// Function overloads do not emit code
// Function overload signature with optional parameter
// Function overload signature with optional parameter
// Function overloads with generic and non-generic overloads
// Function overloads whose only difference is returning different unconstrained generic parameters
// Function overloads whose only difference is returning different constrained generic parameters
// Function overloads that differ only by type parameter constraints
// Function overloads with matching accessibility
// Function overloads with matching export
// Function overloads with more params than implementation signature
// Function overloads where return types are same infinitely recursive type reference

View file

@ -0,0 +1,4 @@
function f(x: string): number;
function f(x: string): void {
return;
}

View file

@ -0,0 +1,4 @@
function f(x: string): void;
function f(x: string): number {
return 0;
}

View file

@ -0,0 +1,4 @@
function f(x: string): void;
function f(x: string): void {
return;
}

View file

@ -0,0 +1,29 @@
//@jsx: preserve
//@module: amd
//@filename: react.d.ts
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
interface IntrinsicAttributes {
ref?: string;
}
}
//@filename: file.tsx
class MyComponent {
render() {
}
props: {
ref?: string;
}
}
// Should be an OK
var x = <MyComponent bar='world' />;

View file

@ -20,7 +20,7 @@ function hasKind(entity: Entity, kind: "A"): entity is A;
function hasKind(entity: Entity, kind: "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is Entity;
function hasKind(entity: Entity, kind: Kind): boolean {
return kind === is;
return entity.kind === kind;
}
let x: A = {

View file

@ -0,0 +1,42 @@
// @declaration: true
type Kind = "A" | "B"
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
function hasKind(entity: Entity, kind: "A"): entity is A;
function hasKind(entity: Entity, kind: "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is (A | B) {
return entity.kind === kind;
}
let x: A = {
kind: "A",
a: 100,
}
if (hasKind(x, "A")) {
let a = x;
}
else {
let b = x;
}
if (!hasKind(x, "B")) {
let c = x;
}
else {
let d = x;
}

View file

@ -0,0 +1,46 @@
// @declaration: true
type Kind = "A" | "B"
interface Entity {
kind: Kind;
}
interface A extends Entity {
kind: "A";
a: number;
}
interface B extends Entity {
kind: "B";
b: string;
}
// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid
// interpreting respective overloads as "specialized" signatures.
// That way, we can avoid the need to look for a compatible overload
// signature and simply check compatibility with the implementation.
function hasKind(entity: Entity, kind: "A" | "A"): entity is A;
function hasKind(entity: Entity, kind: "B" | "B"): entity is B;
function hasKind(entity: Entity, kind: Kind): entity is Entity {
return entity.kind === kind;
}
let x: A = {
kind: "A",
a: 100,
}
if (hasKind(x, "A")) {
let a = x;
}
else {
let b = x;
}
if (!hasKind(x, "B")) {
let c = x;
}
else {
let d = x;
}

View file

@ -9,7 +9,7 @@ function getFalsyPrimitive(x: "boolean" | "string"): boolean | string;
function getFalsyPrimitive(x: "boolean" | "number"): boolean | number;
function getFalsyPrimitive(x: "number" | "string"): number | string;
function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean;
function getFalsyPrimitive(x: PrimitiveName) {
function getFalsyPrimitive(x: PrimitiveName): number | string | boolean {
if (x === "string") {
return "";
}