diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5b6aaa5dabf53..b8d9119ab7070 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7060,8 +7060,8 @@ namespace ts { return signature.resolvedReturnType; } - function isResolvingReturnTypeOfSignature(signature: Signature) { - return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0; + function isResolvingReturnTypeOfSignature(signature: Signature): boolean { + return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0 || (signature.unionSignatures && some(signature.unionSignatures, s => isResolvingReturnTypeOfSignature(s))); } function getRestTypeOfSignature(signature: Signature): Type { @@ -14339,18 +14339,11 @@ namespace ts { // If the given type is an object or union type with a single signature, and if that signature has at // least as many parameters as the given function, return the signature. Otherwise return undefined. - function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { - const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call); - if (signatures.length === 1) { - const signature = signatures[0]; - if (!isAritySmaller(signature, node)) { - return signature; - } - } + function getContextualCallSignatures(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature[] { + return filter(getSignaturesOfStructuredType(type, SignatureKind.Call), s => !isAritySmaller(s, node)); } - /** If the contextual signature has fewer parameters than the function expression, do not use it */ - function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) { + function getMinimumArityOf(target: SignatureDeclaration) { let targetParameterCount = 0; for (; targetParameterCount < target.parameters.length; targetParameterCount++) { const param = target.parameters[targetParameterCount]; @@ -14361,6 +14354,12 @@ namespace ts { if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) { targetParameterCount--; } + return targetParameterCount; + } + + /** If the contextual signature has fewer parameters than the function expression, do not use it */ + function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) { + const targetParameterCount = getMinimumArityOf(target); const sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length; return sourceLength < targetParameterCount; } @@ -14382,6 +14381,96 @@ namespace ts { getApparentTypeOfContextualType(node); } + function combineSignatures(signatureList: Signature[], declaration: SignatureDeclaration): Signature { + // Produce a synthetic signature whose arguments are a union of the parameters of the inferred signatures and whose return type is an intersection + const parameters: Symbol[] = []; + const restTypes: TypeSet = []; + let thisTypes: Type[]; + let hasLiteralTypes = false; + let hasRestParameter = false; + const oldTypeParameters = flatMap(signatureList, s => s.typeParameters); + const newTypeParameters = map(oldTypeParameters, cloneTypeParameter); + const mapper = createTypeMapper(oldTypeParameters, newTypeParameters); + + // First, for every parameter the user has written, lookup a corresponding union of types from the associated signatures + if (declaration.parameters && declaration.parameters.length) { + for (let i = 0; i < declaration.parameters.length ; i++) { + const param = declaration.parameters[i]; + // We do this so the name is reasonable for users; however it is very rare for this symbol name to appear anywhere user-facing, as the result signature is used only for contextual typing + const canUseUserSuppliedName = isIdentifier(param.name); + const paramName = canUseUserSuppliedName ? (param.name as Identifier).escapedText : escapeLeadingUnderscores("arg"); + const paramSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, paramName); + const parameterTypes: TypeSet = []; + if (param.dotDotDotToken) { + hasRestParameter = true; + for (const signature of signatureList) { + for (let j = i; j < signature.parameters.length; j++) { + handleAddingTypesForParameter(signature, j, parameterTypes); + } + } + paramSymbol.type = createArrayType(getUnionType(restTypes ? parameterTypes.concat(restTypes) : parameterTypes)); + parameters.push(paramSymbol); + break; + } + else { + for (const signature of signatureList) { + handleAddingTypesForParameter(signature, i, parameterTypes); + } + paramSymbol.type = getUnionType(restTypes.length ? parameterTypes.concat(restTypes) : parameterTypes); + parameters.push(paramSymbol); + } + } + } + + // Then, collect aggrgate statistics about all signatures to determine the characteristics of the resulting signature + for (const signature of signatureList) { + if (signature.hasLiteralTypes) { + hasLiteralTypes = true; + } + if (signature.thisParameter) { + (thisTypes || (thisTypes = [])).push(instantiateType(getTypeOfSymbol(signature.thisParameter), mapper)); + } + else if (compilerOptions.noImplicitThis) { + (thisTypes || (thisTypes = [])).push(undefinedType); + } + } + + let thisParameterSymbol: TransientSymbol; + if (thisTypes && thisTypes.length) { + thisParameterSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "this" as __String); + thisParameterSymbol.type = getUnionType(thisTypes); + } + + return createSignature( + declaration, + newTypeParameters, + thisParameterSymbol, + parameters, + instantiateType(getIntersectionType(map(signatureList, getReturnTypeOfSignature)), mapper), + /*typePredicate*/ undefined, + getMinimumArityOf(declaration), + hasRestParameter, + hasLiteralTypes + ); + + function handleAddingTypesForParameter(signature: Signature, i: number, parameterTypes: TypeSet) { + const sigParam = signature.parameters[i]; + if (sigParam && !(signature.hasRestParameter && i === (signature.parameters.length - 1))) { + addTypeToUnion(parameterTypes, instantiateType(getTypeOfSymbol(sigParam), mapper)); + return; + } + if (signature.hasRestParameter) { + const innerType = getRestTypeOfSignature(signature) || anyType; + const newInnerType = instantiateType(innerType, mapper); + addTypeToUnion(parameterTypes, newInnerType); + addTypeToUnion(restTypes, newInnerType); + } + if (compilerOptions.strictNullChecks) { + addTypeToUnion(parameterTypes, undefinedType); + } + } + } + // Return the contextual signature for a given expression node. A contextual type provides a // contextual signature if it has a single call signature and if that call signature is non-generic. // If the contextual type is a union type, get the signature from each type possible and if they are @@ -14393,35 +14482,45 @@ namespace ts { if (!type) { return undefined; } + let signatureList: Signature[]; if (!(type.flags & TypeFlags.Union)) { - return getContextualCallSignature(type, node); + signatureList = getContextualCallSignatures(type, node); } - let signatureList: Signature[]; - const types = (type).types; - for (const current of types) { - const signature = getContextualCallSignature(current, node); - if (signature) { - if (!signatureList) { - // This signature will contribute to contextual union signature - signatureList = [signature]; - } - else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { - // Signatures aren't identical, do not use - return undefined; - } - else { - // Use this signature for contextual union signature - signatureList.push(signature); + else { + const types = (type).types; + for (const current of types) { + const signatures = getContextualCallSignatures(current, node); + if (signatures && signatures.length) { + if (!signatureList) { + signatureList = signatures; + } + else { + signatureList = signatureList.concat(signatures); + } } } } - // Result is union of signatures collected (return type is union of return types of this signature set) - let result: Signature; - if (signatureList) { - result = cloneSignature(signatureList[0]); - result.unionSignatures = signatureList; + if (!(signatureList && signatureList.length)) { + return undefined; } + + if (signatureList.length === 1) { + return signatureList[0]; + } + + for (const signature of signatureList) { + if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { + // Signatures not simply identical, combine them + return combineSignatures(signatureList, node); + } + } + + // Result is union of signatures collected (return type is union of return types of this signature set) + const result = cloneSignature(signatureList[0]); + // Clear resolved return type we possibly got from cloneSignature + result.resolvedReturnType = undefined; + result.unionSignatures = signatureList; return result; } @@ -18025,7 +18124,7 @@ namespace ts { if (isUnitType(type)) { let contextualType = !contextualSignature ? undefined : - contextualSignature === getSignatureFromDeclaration(func) ? type : + contextualSignature === getSignatureFromDeclaration(func) || contextualSignature.unionSignatures && some(contextualSignature.unionSignatures, s => s === getSignatureFromDeclaration(func)) ? type : getReturnTypeOfSignature(contextualSignature); if (contextualType) { switch (functionFlags & FunctionFlags.AsyncGenerator) { diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols index 530779be29dfd..a61cd6c3109a2 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols @@ -74,7 +74,9 @@ var x3: IWithCallSignatures | IWithCallSignatures3 = a => /*here a should be any >IWithCallSignatures : Symbol(IWithCallSignatures, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 9, 1)) >IWithCallSignatures3 : Symbol(IWithCallSignatures3, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 15, 1)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 32, 52)) +>a.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 32, 52)) +>toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) // With call signature count mismatch var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any*/ a.toString(); @@ -82,7 +84,7 @@ var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any >IWithCallSignatures : Symbol(IWithCallSignatures, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 9, 1)) >IWithCallSignatures4 : Symbol(IWithCallSignatures4, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 18, 1)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 35, 52)) ->a.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>a.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 35, 52)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types index 8e1915d47549d..a116e85bba0d2 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types @@ -78,22 +78,22 @@ var x3: IWithCallSignatures | IWithCallSignatures3 = a => /*here a should be any >x3 : IWithCallSignatures | IWithCallSignatures3 >IWithCallSignatures : IWithCallSignatures >IWithCallSignatures3 : IWithCallSignatures3 ->a => /*here a should be any*/ a.toString() : (a: any) => any ->a : any ->a.toString() : any ->a.toString : any ->a : any ->toString : any +>a => /*here a should be any*/ a.toString() : (a: string | number) => string +>a : string | number +>a.toString() : string +>a.toString : ((radix?: number) => string) | (() => string) +>a : string | number +>toString : ((radix?: number) => string) | (() => string) // With call signature count mismatch var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any*/ a.toString(); >x4 : IWithCallSignatures | IWithCallSignatures4 >IWithCallSignatures : IWithCallSignatures >IWithCallSignatures4 : IWithCallSignatures4 ->a => /*here a should be any*/ a.toString() : (a: number) => string ->a : number +>a => /*here a should be any*/ a.toString() : (a: string | number) => string +>a : string | number >a.toString() : string ->a.toString : (radix?: number) => string ->a : number ->toString : (radix?: number) => string +>a.toString : ((radix?: number) => string) | (() => string) +>a : string | number +>toString : ((radix?: number) => string) | (() => string) diff --git a/tests/baselines/reference/contextualTyping.errors.txt b/tests/baselines/reference/contextualTyping.errors.txt index 2e050777bfd6a..88bcbaab6b118 100644 --- a/tests/baselines/reference/contextualTyping.errors.txt +++ b/tests/baselines/reference/contextualTyping.errors.txt @@ -1,3 +1,6 @@ +tests/cases/compiler/contextualTyping.ts(36,5): error TS2322: Type '(n: string | number) => string | number' is not assignable to type '{ (n: number): number; (s1: string): number; }'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/contextualTyping.ts(189,18): error TS2384: Overload signatures must all be ambient or non-ambient. tests/cases/compiler/contextualTyping.ts(197,15): error TS2300: Duplicate identifier 'Point'. tests/cases/compiler/contextualTyping.ts(207,10): error TS2300: Duplicate identifier 'Point'. @@ -5,7 +8,7 @@ tests/cases/compiler/contextualTyping.ts(230,5): error TS2322: Type '{}' is not Property 'x' is missing in type '{}'. -==== tests/cases/compiler/contextualTyping.ts (4 errors) ==== +==== tests/cases/compiler/contextualTyping.ts (5 errors) ==== // DEFAULT INTERFACES interface IFoo { n: number; @@ -42,6 +45,10 @@ tests/cases/compiler/contextualTyping.ts(230,5): error TS2322: Type '{}' is not var c3t5: (n: number) => IFoo = function(n) { return ({}) }; var c3t6: (n: number, s: string) => IFoo = function(n, s) { return ({}) }; var c3t7: { + ~~~~ +!!! error TS2322: Type '(n: string | number) => string | number' is not assignable to type '{ (n: number): number; (s1: string): number; }'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. (n: number): number; (s1: string): number; } = function(n) { return n; }; diff --git a/tests/baselines/reference/contextualTyping.types b/tests/baselines/reference/contextualTyping.types index c2379425e1e4f..82435400fe0b2 100644 --- a/tests/baselines/reference/contextualTyping.types +++ b/tests/baselines/reference/contextualTyping.types @@ -126,9 +126,9 @@ var c3t7: { >s1 : string } = function(n) { return n; }; ->function(n) { return n; } : (n: any) => any ->n : any ->n : any +>function(n) { return n; } : (n: string | number) => string | number +>n : string | number +>n : string | number var c3t8: (n: number, s: string) => number = function(n) { return n; }; >c3t8 : (n: number, s: string) => number diff --git a/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures.types b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures.types index 485c7159b77fa..36b7fbb719bcf 100644 --- a/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures.types +++ b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures.types @@ -16,10 +16,10 @@ var foo: Foo; >Foo : Foo foo.getFoo = bar => { }; ->foo.getFoo = bar => { } : (bar: any) => void +>foo.getFoo = bar => { } : (bar: string | number) => void >foo.getFoo : { (n: number): void; (s: string): void; } >foo : Foo >getFoo : { (n: number): void; (s: string): void; } ->bar => { } : (bar: any) => void ->bar : any +>bar => { } : (bar: string | number) => void +>bar : string | number diff --git a/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.errors.txt b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.errors.txt new file mode 100644 index 0000000000000..711fb848240d6 --- /dev/null +++ b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/contextualTypingOfLambdaWithMultipleSignatures2.ts(6,23): error TS2339: Property 'asdf' does not exist on type 'string | number'. + Property 'asdf' does not exist on type 'string'. + + +==== tests/cases/compiler/contextualTypingOfLambdaWithMultipleSignatures2.ts (1 errors) ==== + var f: { + (x: string): string; + (x: number): string + }; + + f = (a) => { return a.asdf } + ~~~~ +!!! error TS2339: Property 'asdf' does not exist on type 'string | number'. +!!! error TS2339: Property 'asdf' does not exist on type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.types b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.types index 1b7f328b5f1c6..49cb3294aaf15 100644 --- a/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.types +++ b/tests/baselines/reference/contextualTypingOfLambdaWithMultipleSignatures2.types @@ -11,11 +11,11 @@ var f: { }; f = (a) => { return a.asdf } ->f = (a) => { return a.asdf } : (a: any) => any +>f = (a) => { return a.asdf } : (a: string | number) => any >f : { (x: string): string; (x: number): string; } ->(a) => { return a.asdf } : (a: any) => any ->a : any +>(a) => { return a.asdf } : (a: string | number) => any +>a : string | number >a.asdf : any ->a : any +>a : string | number >asdf : any diff --git a/tests/baselines/reference/contextualTypingWithGenericAndNonGenericSignature.types b/tests/baselines/reference/contextualTypingWithGenericAndNonGenericSignature.types index ca6c5b35f3d0e..d4202e02adb98 100644 --- a/tests/baselines/reference/contextualTypingWithGenericAndNonGenericSignature.types +++ b/tests/baselines/reference/contextualTypingWithGenericAndNonGenericSignature.types @@ -20,12 +20,12 @@ var f2: { }; f2 = (x, y) => { return x } ->f2 = (x, y) => { return x } : (x: any, y: any) => any +>f2 = (x, y) => { return x } : (x: string | T, y: number | U) => string | T >f2 : { (x: string, y: number): string; (x: T, y: U): T; } ->(x, y) => { return x } : (x: any, y: any) => any ->x : any ->y : any ->x : any +>(x, y) => { return x } : (x: string | T, y: number | U) => string | T +>x : string | T +>y : number | U +>x : string | T var f3: { >f3 : { (x: T, y: U): T; (x: string, y: number): string; } @@ -46,10 +46,10 @@ var f3: { }; f3 = (x, y) => { return x } ->f3 = (x, y) => { return x } : (x: any, y: any) => any +>f3 = (x, y) => { return x } : (x: string | T, y: number | U) => string | T >f3 : { (x: T, y: U): T; (x: string, y: number): string; } ->(x, y) => { return x } : (x: any, y: any) => any ->x : any ->y : any ->x : any +>(x, y) => { return x } : (x: string | T, y: number | U) => string | T +>x : string | T +>y : number | U +>x : string | T diff --git a/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt b/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt new file mode 100644 index 0000000000000..5170118d0f9aa --- /dev/null +++ b/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt @@ -0,0 +1,80 @@ +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(43,17): error TS2339: Property 'toLowerCase' does not exist on type 'string | number'. + Property 'toLowerCase' does not exist on type 'number'. +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(45,7): error TS2339: Property 'toExponential' does not exist on type 'string | number'. + Property 'toExponential' does not exist on type 'string'. +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(52,13): error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '((j: T, k: U) => (T | U)[]) | ((j: number, k: U) => number[])'. + Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '(j: number, k: U) => number[]'. + Type '(number | T | U)[]' is not assignable to type 'number[]'. + Type 'number | T | U' is not assignable to type 'number'. + Type 'T' is not assignable to type 'number'. + + +==== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts (3 errors) ==== + // When a function expression with no type parameters and no parameter type annotations + // is contextually typed (section 4.19) by a type T and a contextual signature S can be extracted from T + + enum E { red, blue } + + // A contextual signature S is extracted from a function type T as follows: + // If T is a function type with exactly one call signature, and if that call signature is non- generic, S is that signature. + + var a0: (n: number, s: string) => number = (num, str) => { + num.toExponential(); + return 0; + } + + class Class { + foo() { } + } + + var a1: (c: Class) => number = (a1) => { + a1.foo(); + return 1; + } + + // A contextual signature S is extracted from a function type T as follows: + // If T is a union type, let U be the set of element types in T that have call signatures. + // If each type in U has exactly one call signature and that call signature is non- generic, + // and if all of the signatures are identical ignoring return types, + // then S is a signature with the same parameters and a union of the return types. + var b1: ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string); + b1 = (k, h) => { }; + var b2: typeof a0 | ((n: number, s: string) => string); + b2 = (foo, bar) => { return foo + 1; } + b2 = (foo, bar) => { return "hello"; } + var b3: (name: string, num: number, boo: boolean) => void; + b3 = (name, number) => { }; + + var b4: (n: E) => string = (number = 1) => { return "hello"; }; + var b5: (n: {}) => string = (number = "string") => { return "hello"; }; + + // A contextual signature S is extracted from a function type T as follows: + // Otherwise, no contextual signature can be extracted from T and S is undefined. + var b6: ((s: string, w: boolean) => void) | ((n: number) => number); + var b7: ((s: string, w: boolean) => void) | ((s: string, w: number) => string); + b6 = (k) => { k.toLowerCase() }; + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'string | number'. +!!! error TS2339: Property 'toLowerCase' does not exist on type 'number'. + b6 = (i) => { + i.toExponential(); + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'toExponential' does not exist on type 'string | number'. +!!! error TS2339: Property 'toExponential' does not exist on type 'string'. + return i; + }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) + b7 = (j, m) => { }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) + + class C { + constructor() { + var k: ((j: T, k: U) => (T|U)[]) | ((j: number,k :U) => number[]) = (j, k) => { + ~ +!!! error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '((j: T, k: U) => (T | U)[]) | ((j: number, k: U) => number[])'. +!!! error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '(j: number, k: U) => number[]'. +!!! error TS2322: Type '(number | T | U)[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'number | T | U' is not assignable to type 'number'. +!!! error TS2322: Type 'T' is not assignable to type 'number'. + return [j, k]; + } // Per spec, no contextual signature can be extracted in this case. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/functionExpressionContextualTyping1.types b/tests/baselines/reference/functionExpressionContextualTyping1.types index 58265c74aa29e..7eea6060d0d67 100644 --- a/tests/baselines/reference/functionExpressionContextualTyping1.types +++ b/tests/baselines/reference/functionExpressionContextualTyping1.types @@ -143,37 +143,37 @@ var b7: ((s: string, w: boolean) => void) | ((s: string, w: number) => string); >w : number b6 = (k) => { k.toLowerCase() }; ->b6 = (k) => { k.toLowerCase() } : (k: any) => void +>b6 = (k) => { k.toLowerCase() } : (k: string | number) => void >b6 : ((s: string, w: boolean) => void) | ((n: number) => number) ->(k) => { k.toLowerCase() } : (k: any) => void ->k : any +>(k) => { k.toLowerCase() } : (k: string | number) => void +>k : string | number >k.toLowerCase() : any >k.toLowerCase : any ->k : any +>k : string | number >toLowerCase : any b6 = (i) => { ->b6 = (i) => { i.toExponential(); return i;} : (i: any) => any +>b6 = (i) => { i.toExponential(); return i;} : (i: string | number) => string | number >b6 : ((s: string, w: boolean) => void) | ((n: number) => number) ->(i) => { i.toExponential(); return i;} : (i: any) => any ->i : any +>(i) => { i.toExponential(); return i;} : (i: string | number) => string | number +>i : string | number i.toExponential(); >i.toExponential() : any >i.toExponential : any ->i : any +>i : string | number >toExponential : any return i; ->i : any +>i : string | number }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) b7 = (j, m) => { }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) ->b7 = (j, m) => { } : (j: any, m: any) => void +>b7 = (j, m) => { } : (j: string, m: number | boolean) => void >b7 : ((s: string, w: boolean) => void) | ((s: string, w: number) => string) ->(j, m) => { } : (j: any, m: any) => void ->j : any ->m : any +>(j, m) => { } : (j: string, m: number | boolean) => void +>j : string +>m : number | boolean class C { >C : C @@ -192,14 +192,14 @@ class C { >j : number >k : U >U : U ->(j, k) => { return [j, k]; } : (j: any, k: any) => any[] ->j : any ->k : any +>(j, k) => { return [j, k]; } : (j: number | T, k: U) => (number | T | U)[] +>j : number | T +>k : U return [j, k]; ->[j, k] : any[] ->j : any ->k : any +>[j, k] : (number | T | U)[] +>j : number | T +>k : U } // Per spec, no contextual signature can be extracted in this case. } diff --git a/tests/baselines/reference/functionLiteralForOverloads.errors.txt b/tests/baselines/reference/functionLiteralForOverloads.errors.txt new file mode 100644 index 0000000000000..64a53582f34be --- /dev/null +++ b/tests/baselines/reference/functionLiteralForOverloads.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/types/specifyingTypes/typeLiterals/functionLiteralForOverloads.ts(3,5): error TS2322: Type '(x: string | number) => string | number' is not assignable to type '{ (x: string): string; (x: number): number; }'. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/specifyingTypes/typeLiterals/functionLiteralForOverloads.ts(8,5): error TS2322: Type '(x: string | number) => string | number' is not assignable to type '{ (x: string): string; (x: number): number; }'. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/specifyingTypes/typeLiterals/functionLiteralForOverloads.ts (2 errors) ==== + // basic uses of function literals with overloads + + var f: { + ~ +!!! error TS2322: Type '(x: string | number) => string | number' is not assignable to type '{ (x: string): string; (x: number): number; }'. +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + (x: string): string; + (x: number): number; + } = (x) => x; + + var f2: { + ~~ +!!! error TS2322: Type '(x: string | number) => string | number' is not assignable to type '{ (x: string): string; (x: number): number; }'. +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + (x: string): string; + (x: number): number; + } = (x) => x; + + var f3: { + (x: T): string; + (x: T): number; + } = (x) => x; + + var f4: { + (x: string): T; + (x: number): T; + } = (x) => x; \ No newline at end of file diff --git a/tests/baselines/reference/functionLiteralForOverloads.types b/tests/baselines/reference/functionLiteralForOverloads.types index b04238b4ce41b..cb02d472e0e1f 100644 --- a/tests/baselines/reference/functionLiteralForOverloads.types +++ b/tests/baselines/reference/functionLiteralForOverloads.types @@ -11,9 +11,9 @@ var f: { >x : number } = (x) => x; ->(x) => x : (x: any) => any ->x : any ->x : any +>(x) => x : (x: string | number) => string | number +>x : string | number +>x : string | number var f2: { >f2 : { (x: string): string; (x: number): number; } @@ -27,9 +27,9 @@ var f2: { >x : number } = (x) => x; ->(x) => x : (x: any) => any ->x : any ->x : any +>(x) => x : (x: string | number) => string | number +>x : string | number +>x : string | number var f3: { >f3 : { (x: T): string; (x: T): number; } @@ -45,9 +45,9 @@ var f3: { >T : T } = (x) => x; ->(x) => x : (x: any) => any ->x : any ->x : any +>(x) => x : (x: T) => T +>x : T +>x : T var f4: { >f4 : { (x: string): T; (x: number): T; } @@ -63,7 +63,7 @@ var f4: { >T : T } = (x) => x; ->(x) => x : (x: any) => any ->x : any ->x : any +>(x) => x : (x: string | number) => string | number +>x : string | number +>x : string | number diff --git a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.errors.txt b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.errors.txt new file mode 100644 index 0000000000000..379a6c56e496b --- /dev/null +++ b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.errors.txt @@ -0,0 +1,71 @@ +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments.ts(16,19): error TS2345: Argument of type '(x: string | boolean) => string | boolean' is not assignable to parameter of type '{ (x: boolean): boolean; (x: string): string; }'. + Type 'string | boolean' is not assignable to type 'boolean'. + Type 'string' is not assignable to type 'boolean'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments.ts(24,19): error TS2345: Argument of type '(x: number | {}) => number | {}' is not assignable to parameter of type '{ (x: {}): string; (x: number): {}; }'. + Type 'number | {}' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments.ts(32,19): error TS2345: Argument of type '(x: {}) => {}' is not assignable to parameter of type '{ (x: {}): string; (x: {}, y?: {}): string; }'. + Type '{}' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments.ts(40,23): error TS2345: Argument of type '(x: number) => number' is not assignable to parameter of type '{ (x: number): string; (x: number, y?: number): string; }'. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments.ts (4 errors) ==== + // Function typed arguments with multiple signatures must be passed an implementation that matches all of them + // Inferences are made quadratic-pairwise to and from these overload sets + + module NonGenericParameter { + var a: { + (x: boolean): boolean; + (x: string): string; + } + + function foo4(cb: typeof a) { + return cb; + } + + var r = foo4(a); + var r2 = foo4((x: T) => x); + var r4 = foo4(x => x); + ~~~~~~ +!!! error TS2345: Argument of type '(x: string | boolean) => string | boolean' is not assignable to parameter of type '{ (x: boolean): boolean; (x: string): string; }'. +!!! error TS2345: Type 'string | boolean' is not assignable to type 'boolean'. +!!! error TS2345: Type 'string' is not assignable to type 'boolean'. + } + + module GenericParameter { + function foo5(cb: { (x: T): string; (x: number): T }) { + return cb; + } + + var r5 = foo5(x => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed]. T is any + ~~~~~~ +!!! error TS2345: Argument of type '(x: number | {}) => number | {}' is not assignable to parameter of type '{ (x: {}): string; (x: number): {}; }'. +!!! error TS2345: Type 'number | {}' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + var a: { (x: T): string; (x: number): T; } + var r7 = foo5(a); // any => string (+1 overload) + + function foo6(cb: { (x: T): string; (x: T, y?: T): string }) { + return cb; + } + + var r8 = foo6(x => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed]. T is any + ~~~~~~ +!!! error TS2345: Argument of type '(x: {}) => {}' is not assignable to parameter of type '{ (x: {}): string; (x: {}, y?: {}): string; }'. +!!! error TS2345: Type '{}' is not assignable to type 'string'. + var r9 = foo6((x: T) => ''); // any => string (+1 overload) + var r11 = foo6((x: T, y?: T) => ''); // any => string (+1 overload) + + function foo7(x:T, cb: { (x: T): string; (x: T, y?: T): string }) { + return cb; + } + + var r12 = foo7(1, (x) => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] + ~~~~~~~~ +!!! error TS2345: Argument of type '(x: number) => number' is not assignable to parameter of type '{ (x: number): string; (x: number, y?: number): string; }'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + var r13 = foo7(1, (x: T) => ''); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] + var a: { (x: T): string; (x: number): T; } + var r14 = foo7(1, a); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] + } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types index 55bec0c2a9f3a..57a7aa2db945c 100644 --- a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types +++ b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types @@ -44,9 +44,9 @@ module NonGenericParameter { >r4 : { (x: boolean): boolean; (x: string): string; } >foo4(x => x) : { (x: boolean): boolean; (x: string): string; } >foo4 : (cb: { (x: boolean): boolean; (x: string): string; }) => { (x: boolean): boolean; (x: string): string; } ->x => x : (x: any) => any ->x : any ->x : any +>x => x : (x: string | boolean) => string | boolean +>x : string | boolean +>x : string | boolean } module GenericParameter { @@ -66,12 +66,12 @@ module GenericParameter { } var r5 = foo5(x => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed]. T is any ->r5 : { (x: any): string; (x: number): any; } ->foo5(x => x) : { (x: any): string; (x: number): any; } +>r5 : any +>foo5(x => x) : any >foo5 : (cb: { (x: T): string; (x: number): T; }) => { (x: T): string; (x: number): T; } ->x => x : (x: any) => any ->x : any ->x : any +>x => x : (x: number | {}) => number | {} +>x : number | {} +>x : number | {} var a: { (x: T): string; (x: number): T; } >a : { (x: T): string; (x: number): T; } @@ -104,12 +104,12 @@ module GenericParameter { } var r8 = foo6(x => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed]. T is any ->r8 : { (x: any): string; (x: any, y?: any): string; } ->foo6(x => x) : { (x: any): string; (x: any, y?: any): string; } +>r8 : any +>foo6(x => x) : any >foo6 : (cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } ->x => x : (x: any) => any ->x : any ->x : any +>x => x : (x: {}) => {} +>x : {} +>x : {} var r9 = foo6((x: T) => ''); // any => string (+1 overload) >r9 : { (x: {}): string; (x: {}, y?: {}): string; } @@ -151,13 +151,13 @@ module GenericParameter { } var r12 = foo7(1, (x) => x); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] ->r12 : { (x: any): string; (x: any, y?: any): string; } ->foo7(1, (x) => x) : { (x: any): string; (x: any, y?: any): string; } +>r12 : any +>foo7(1, (x) => x) : any >foo7 : (x: T, cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >1 : 1 ->(x) => x : (x: any) => any ->x : any ->x : any +>(x) => x : (x: number) => number +>x : number +>x : number var r13 = foo7(1, (x: T) => ''); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] >r13 : { (x: {}): string; (x: {}, y?: {}): string; } diff --git a/tests/baselines/reference/restParameterContextualTypes.js b/tests/baselines/reference/restParameterContextualTypes.js new file mode 100644 index 0000000000000..321def08fa305 --- /dev/null +++ b/tests/baselines/reference/restParameterContextualTypes.js @@ -0,0 +1,53 @@ +//// [restParameterContextualTypes.ts] +type ComplexCalls = { + (): string; + (a: number): string; + (a: {x: number}, b: string): string; + (a: symbol, ...rest: {y: string}[]): string; + (...rest: {z: string}[]): string; +}; + +const x: ComplexCalls = (...rest) => rest.toString(); + +const y: ComplexCalls = (_a = 1, ...rest) => rest.toString(); + +const z: ComplexCalls = (_a = 1, _b = "", ...rest) => rest.toString(); + +const more: ComplexCalls = (_a = 1, _b = "", _c = { z: "" }, ...rest) => rest.toString(); + + +//// [restParameterContextualTypes.js] +var x = function () { + var rest = []; + for (var _i = 0; _i < arguments.length; _i++) { + rest[_i] = arguments[_i]; + } + return rest.toString(); +}; +var y = function (_a) { + if (_a === void 0) { _a = 1; } + var rest = []; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; + } + return rest.toString(); +}; +var z = function (_a, _b) { + if (_a === void 0) { _a = 1; } + if (_b === void 0) { _b = ""; } + var rest = []; + for (var _i = 2; _i < arguments.length; _i++) { + rest[_i - 2] = arguments[_i]; + } + return rest.toString(); +}; +var more = function (_a, _b, _c) { + if (_a === void 0) { _a = 1; } + if (_b === void 0) { _b = ""; } + if (_c === void 0) { _c = { z: "" }; } + var rest = []; + for (var _i = 3; _i < arguments.length; _i++) { + rest[_i - 3] = arguments[_i]; + } + return rest.toString(); +}; diff --git a/tests/baselines/reference/restParameterContextualTypes.symbols b/tests/baselines/reference/restParameterContextualTypes.symbols new file mode 100644 index 0000000000000..1ccacc504cae2 --- /dev/null +++ b/tests/baselines/reference/restParameterContextualTypes.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/restParameterContextualTypes.ts === +type ComplexCalls = { +>ComplexCalls : Symbol(ComplexCalls, Decl(restParameterContextualTypes.ts, 0, 0)) + + (): string; + (a: number): string; +>a : Symbol(a, Decl(restParameterContextualTypes.ts, 2, 5)) + + (a: {x: number}, b: string): string; +>a : Symbol(a, Decl(restParameterContextualTypes.ts, 3, 5)) +>x : Symbol(x, Decl(restParameterContextualTypes.ts, 3, 9)) +>b : Symbol(b, Decl(restParameterContextualTypes.ts, 3, 20)) + + (a: symbol, ...rest: {y: string}[]): string; +>a : Symbol(a, Decl(restParameterContextualTypes.ts, 4, 5)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 4, 15)) +>y : Symbol(y, Decl(restParameterContextualTypes.ts, 4, 26)) + + (...rest: {z: string}[]): string; +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 5, 5)) +>z : Symbol(z, Decl(restParameterContextualTypes.ts, 5, 15)) + +}; + +const x: ComplexCalls = (...rest) => rest.toString(); +>x : Symbol(x, Decl(restParameterContextualTypes.ts, 8, 5)) +>ComplexCalls : Symbol(ComplexCalls, Decl(restParameterContextualTypes.ts, 0, 0)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 8, 25)) +>rest.toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 8, 25)) +>toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) + +const y: ComplexCalls = (_a = 1, ...rest) => rest.toString(); +>y : Symbol(y, Decl(restParameterContextualTypes.ts, 10, 5)) +>ComplexCalls : Symbol(ComplexCalls, Decl(restParameterContextualTypes.ts, 0, 0)) +>_a : Symbol(_a, Decl(restParameterContextualTypes.ts, 10, 25)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 10, 32)) +>rest.toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 10, 32)) +>toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) + +const z: ComplexCalls = (_a = 1, _b = "", ...rest) => rest.toString(); +>z : Symbol(z, Decl(restParameterContextualTypes.ts, 12, 5)) +>ComplexCalls : Symbol(ComplexCalls, Decl(restParameterContextualTypes.ts, 0, 0)) +>_a : Symbol(_a, Decl(restParameterContextualTypes.ts, 12, 25)) +>_b : Symbol(_b, Decl(restParameterContextualTypes.ts, 12, 32)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 12, 41)) +>rest.toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 12, 41)) +>toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) + +const more: ComplexCalls = (_a = 1, _b = "", _c = { z: "" }, ...rest) => rest.toString(); +>more : Symbol(more, Decl(restParameterContextualTypes.ts, 14, 5)) +>ComplexCalls : Symbol(ComplexCalls, Decl(restParameterContextualTypes.ts, 0, 0)) +>_a : Symbol(_a, Decl(restParameterContextualTypes.ts, 14, 28)) +>_b : Symbol(_b, Decl(restParameterContextualTypes.ts, 14, 35)) +>_c : Symbol(_c, Decl(restParameterContextualTypes.ts, 14, 44)) +>z : Symbol(z, Decl(restParameterContextualTypes.ts, 14, 51)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 14, 60)) +>rest.toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) +>rest : Symbol(rest, Decl(restParameterContextualTypes.ts, 14, 60)) +>toString : Symbol(Array.toString, Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/restParameterContextualTypes.types b/tests/baselines/reference/restParameterContextualTypes.types new file mode 100644 index 0000000000000..1573ed07491d7 --- /dev/null +++ b/tests/baselines/reference/restParameterContextualTypes.types @@ -0,0 +1,78 @@ +=== tests/cases/compiler/restParameterContextualTypes.ts === +type ComplexCalls = { +>ComplexCalls : ComplexCalls + + (): string; + (a: number): string; +>a : number + + (a: {x: number}, b: string): string; +>a : { x: number; } +>x : number +>b : string + + (a: symbol, ...rest: {y: string}[]): string; +>a : symbol +>rest : { y: string; }[] +>y : string + + (...rest: {z: string}[]): string; +>rest : { z: string; }[] +>z : string + +}; + +const x: ComplexCalls = (...rest) => rest.toString(); +>x : ComplexCalls +>ComplexCalls : ComplexCalls +>(...rest) => rest.toString() : (...rest: (string | number | symbol | { x: number; } | { y: string; } | { z: string; } | undefined)[]) => string +>rest : (string | number | symbol | { x: number; } | { y: string; } | { z: string; } | undefined)[] +>rest.toString() : string +>rest.toString : () => string +>rest : (string | number | symbol | { x: number; } | { y: string; } | { z: string; } | undefined)[] +>toString : () => string + +const y: ComplexCalls = (_a = 1, ...rest) => rest.toString(); +>y : ComplexCalls +>ComplexCalls : ComplexCalls +>(_a = 1, ...rest) => rest.toString() : (_a?: number | symbol | { x: number; } | { z: string; } | undefined, ...rest: (string | { y: string; } | { z: string; } | undefined)[]) => string +>_a : number | symbol | { x: number; } | { z: string; } | undefined +>1 : 1 +>rest : (string | { y: string; } | { z: string; } | undefined)[] +>rest.toString() : string +>rest.toString : () => string +>rest : (string | { y: string; } | { z: string; } | undefined)[] +>toString : () => string + +const z: ComplexCalls = (_a = 1, _b = "", ...rest) => rest.toString(); +>z : ComplexCalls +>ComplexCalls : ComplexCalls +>(_a = 1, _b = "", ...rest) => rest.toString() : (_a?: number | symbol | { x: number; } | { z: string; } | undefined, _b?: string | { y: string; } | { z: string; } | undefined, ...rest: ({ y: string; } | { z: string; })[]) => string +>_a : number | symbol | { x: number; } | { z: string; } | undefined +>1 : 1 +>_b : string | { y: string; } | { z: string; } | undefined +>"" : "" +>rest : ({ y: string; } | { z: string; })[] +>rest.toString() : string +>rest.toString : () => string +>rest : ({ y: string; } | { z: string; })[] +>toString : () => string + +const more: ComplexCalls = (_a = 1, _b = "", _c = { z: "" }, ...rest) => rest.toString(); +>more : ComplexCalls +>ComplexCalls : ComplexCalls +>(_a = 1, _b = "", _c = { z: "" }, ...rest) => rest.toString() : (_a?: number | symbol | { x: number; } | { z: string; } | undefined, _b?: string | { y: string; } | { z: string; } | undefined, _c?: { y: string; } | { z: string; } | undefined, ...rest: ({ y: string; } | { z: string; })[]) => string +>_a : number | symbol | { x: number; } | { z: string; } | undefined +>1 : 1 +>_b : string | { y: string; } | { z: string; } | undefined +>"" : "" +>_c : { y: string; } | { z: string; } | undefined +>{ z: "" } : { z: string; } +>z : string +>"" : "" +>rest : ({ y: string; } | { z: string; })[] +>rest.toString() : string +>rest.toString : () => string +>rest : ({ y: string; } | { z: string; })[] +>toString : () => string + diff --git a/tests/baselines/reference/tsxRefInference.js b/tests/baselines/reference/tsxRefInference.js new file mode 100644 index 0000000000000..cd72c821d952d --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.js @@ -0,0 +1,255 @@ +//// [tests/cases/compiler/tsxRefInference.tsx] //// + +//// [index.d.ts] +export as namespace React; +export = React; + +declare namespace React { + interface SyntheticEvent { + bubbles: boolean; + currentTarget: EventTarget & T; + cancelable: boolean; + defaultPrevented: boolean; + eventPhase: number; + isTrusted: boolean; + nativeEvent: Event; + preventDefault(): void; + isDefaultPrevented(): boolean; + stopPropagation(): void; + isPropagationStopped(): boolean; + persist(): void; + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; + timeStamp: number; + type: string; + } + + interface ChangeEvent extends SyntheticEvent { + target: EventTarget & T; + } + + interface FormEvent extends SyntheticEvent { + } + + interface DOMAttributes { + onChange?: FormEventHandler; + onChangeCapture?: FormEventHandler; + onInput?: FormEventHandler; + onInputCapture?: FormEventHandler; + onReset?: FormEventHandler; + onResetCapture?: FormEventHandler; + onSubmit?: FormEventHandler; + onSubmitCapture?: FormEventHandler; + onInvalid?: FormEventHandler; + onInvalidCapture?: FormEventHandler; + } + + interface HTMLAttributes extends DOMAttributes {} + + interface InputHTMLAttributes extends HTMLAttributes { + onChange?: ChangeEventHandler; + } + + type FormEventHandler = EventHandler>; + type ChangeEventHandler = EventHandler>; + type EventHandler> = (event: E) => void; + type DetailedHTMLProps, T> = ClassAttributes & E; + + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + type Key = string | number; + type Ref = string | ((instance: T | null) => any); + + interface Component

extends ComponentLifecycle {} + + interface ComponentLifecycle { + componentWillMount?(): void; + componentDidMount?(): void; + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; + componentWillUnmount?(): void; + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; + } + + interface ErrorInfo { + componentStack: string; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; + props: P; + key: Key | null; + } + + interface SFCElement

extends ReactElement

{ + type: SFC

; + } + + type ComponentState = {}; + type ClassType, C extends ComponentClass

> = + & C + & (new (props?: P, context?: any) => T) + & (new (props?: P, context?: any) => { props: P }); + + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; + } + + interface ClassicComponent

extends Component { + replaceState(nextState: S, callback?: () => any): void; + isMounted(): boolean; + getInitialState?(): S; + } + + interface ClassicComponentClass

extends ComponentClass

{ + new (props?: P, context?: any): ClassicComponent; + getDefaultProps?(): P; + } + + type SFC

= StatelessComponent

; + interface StatelessComponent

{ + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactChild = ReactElement | ReactText; + type ReactText = string | number; + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; + + interface ComponentClass

{ + new (props?: P, context?: any): Component; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + childContextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ValidationMap = {[K in keyof T]?: Validator }; + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; + + function createElement

( + type: SFC

, + props?: Attributes & P, + ...children: ReactNode[]): SFCElement

; + function createElement

( + type: ClassType, ClassicComponentClass

>, + props?: ClassAttributes> & P, + ...children: ReactNode[]): CElement>; + function createElement, C extends ComponentClass

>( + type: ClassType, + props?: ClassAttributes & P, + ...children: ReactNode[]): CElement; + function createElement

( + type: ComponentClass

, + props?: Attributes & P, + ...children: ReactNode[]): ReactElement

; +} + +declare global { + namespace JSX { + interface Element extends React.ReactElement {} + interface ElementClass extends React.Component { + render(): JSX.Element | null | false; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + + interface IntrinsicAttributes extends React.Attributes {} + interface IntrinsicClassAttributes extends React.ClassAttributes {} + + interface IntrinsicElements { + input: React.DetailedHTMLProps, HTMLInputElement>; + } + } +} + +//// [index.tsx] +import React = require("react"); + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { + onValid?(): boolean; + onInvalid?(): boolean; +} + +class MyInput implements React.Component { + props: MyInputProps; + render() { + const { onValid, onInvalid, onChange, ...inputProps } = this.props; + return ( + + ); + } + + componentDidMount() {} + + private _onChange(event: React.ChangeEvent) { + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + } +} + +function someFunction() {} +const x = 0} onChange={someFunction} />; + +//// [index.js] +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +exports.__esModule = true; +var React = require("react"); +var MyInput = /** @class */ (function () { + function MyInput() { + } + MyInput.prototype.render = function () { + var _a = this.props, onValid = _a.onValid, onInvalid = _a.onInvalid, onChange = _a.onChange, inputProps = __rest(_a, ["onValid", "onInvalid", "onChange"]); + return (React.createElement("input", __assign({}, inputProps, { onChange: this._onChange }))); + }; + MyInput.prototype.componentDidMount = function () { }; + MyInput.prototype._onChange = function (event) { + // do some validation first... + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + }; + return MyInput; +}()); +function someFunction() { } +var x = React.createElement(MyInput, { ref: function (r) { return 0; }, onChange: someFunction }); diff --git a/tests/baselines/reference/tsxRefInference.symbols b/tests/baselines/reference/tsxRefInference.symbols new file mode 100644 index 0000000000000..7c7a3e10c5896 --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.symbols @@ -0,0 +1,796 @@ +=== tests/cases/compiler/index.tsx === +import React = require("react"); +>React : Symbol(React, Decl(index.tsx, 0, 0)) + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) +>React.DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>InputHTMLAttributes : Symbol(React.InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + onValid?(): boolean; +>onValid : Symbol(MyInputProps.onValid, Decl(index.tsx, 2, 120)) + + onInvalid?(): boolean; +>onInvalid : Symbol(MyInputProps.onInvalid, Decl(index.tsx, 3, 24)) +} + +class MyInput implements React.Component { +>MyInput : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>React.Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) + + props: MyInputProps; +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) + + render() { +>render : Symbol(MyInput.render, Decl(index.tsx, 8, 24)) + + const { onValid, onInvalid, onChange, ...inputProps } = this.props; +>onValid : Symbol(onValid, Decl(index.tsx, 10, 15)) +>onInvalid : Symbol(onInvalid, Decl(index.tsx, 10, 24)) +>onChange : Symbol(onChange, Decl(index.tsx, 10, 35)) +>inputProps : Symbol(inputProps, Decl(index.tsx, 10, 45)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) + + return ( + input : Symbol(JSX.IntrinsicElements.input, Decl(index.d.ts, 171, 37)) + + { ...inputProps } +>inputProps : Symbol(inputProps, Decl(index.tsx, 10, 45)) + + onChange={ this._onChange } +>onChange : Symbol(onChange, Decl(index.tsx, 13, 33)) +>this._onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>_onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) + + /> + ); + } + + componentDidMount() {} +>componentDidMount : Symbol(MyInput.componentDidMount, Decl(index.tsx, 17, 5)) + + private _onChange(event: React.ChangeEvent) { +>_onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) +>event : Symbol(event, Decl(index.tsx, 21, 22)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>ChangeEvent : Symbol(React.ChangeEvent, Decl(index.d.ts, 21, 5)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { +>this.props.onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) + + this.props.onChange(event); +>this.props.onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>event : Symbol(event, Decl(index.tsx, 21, 22)) + } + } +} + +function someFunction() {} +>someFunction : Symbol(someFunction, Decl(index.tsx, 29, 1)) + +const x = 0} onChange={someFunction} />; +>x : Symbol(x, Decl(index.tsx, 32, 5)) +>MyInput : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>ref : Symbol(ref, Decl(index.tsx, 32, 18)) +>r : Symbol(r, Decl(index.tsx, 32, 24)) +>onChange : Symbol(onChange, Decl(index.tsx, 32, 31)) +>someFunction : Symbol(someFunction, Decl(index.tsx, 29, 1)) + +=== tests/cases/compiler/node_modules/react/index.d.ts === +export as namespace React; +>React : Symbol(React, Decl(index.d.ts, 0, 0)) + +export = React; +>React : Symbol(React, Decl(index.d.ts, 1, 15)) + +declare namespace React { +>React : Symbol(React, Decl(index.d.ts, 1, 15)) + + interface SyntheticEvent { +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 4, 29)) + + bubbles: boolean; +>bubbles : Symbol(SyntheticEvent.bubbles, Decl(index.d.ts, 4, 33)) + + currentTarget: EventTarget & T; +>currentTarget : Symbol(SyntheticEvent.currentTarget, Decl(index.d.ts, 5, 25)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>T : Symbol(T, Decl(index.d.ts, 4, 29)) + + cancelable: boolean; +>cancelable : Symbol(SyntheticEvent.cancelable, Decl(index.d.ts, 6, 39)) + + defaultPrevented: boolean; +>defaultPrevented : Symbol(SyntheticEvent.defaultPrevented, Decl(index.d.ts, 7, 28)) + + eventPhase: number; +>eventPhase : Symbol(SyntheticEvent.eventPhase, Decl(index.d.ts, 8, 34)) + + isTrusted: boolean; +>isTrusted : Symbol(SyntheticEvent.isTrusted, Decl(index.d.ts, 9, 27)) + + nativeEvent: Event; +>nativeEvent : Symbol(SyntheticEvent.nativeEvent, Decl(index.d.ts, 10, 27)) +>Event : Symbol(Event, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + preventDefault(): void; +>preventDefault : Symbol(SyntheticEvent.preventDefault, Decl(index.d.ts, 11, 27)) + + isDefaultPrevented(): boolean; +>isDefaultPrevented : Symbol(SyntheticEvent.isDefaultPrevented, Decl(index.d.ts, 12, 31)) + + stopPropagation(): void; +>stopPropagation : Symbol(SyntheticEvent.stopPropagation, Decl(index.d.ts, 13, 38)) + + isPropagationStopped(): boolean; +>isPropagationStopped : Symbol(SyntheticEvent.isPropagationStopped, Decl(index.d.ts, 14, 32)) + + persist(): void; +>persist : Symbol(SyntheticEvent.persist, Decl(index.d.ts, 15, 40)) + + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; +>target : Symbol(SyntheticEvent.target, Decl(index.d.ts, 16, 24)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + timeStamp: number; +>timeStamp : Symbol(SyntheticEvent.timeStamp, Decl(index.d.ts, 18, 28)) + + type: string; +>type : Symbol(SyntheticEvent.type, Decl(index.d.ts, 19, 26)) + } + + interface ChangeEvent extends SyntheticEvent { +>ChangeEvent : Symbol(ChangeEvent, Decl(index.d.ts, 21, 5)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) + + target: EventTarget & T; +>target : Symbol(ChangeEvent.target, Decl(index.d.ts, 23, 56)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) + } + + interface FormEvent extends SyntheticEvent { +>FormEvent : Symbol(FormEvent, Decl(index.d.ts, 25, 5)) +>T : Symbol(T, Decl(index.d.ts, 27, 24)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 27, 24)) + } + + interface DOMAttributes { +>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 28, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onChange?: FormEventHandler; +>onChange : Symbol(DOMAttributes.onChange, Decl(index.d.ts, 30, 32)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onChangeCapture?: FormEventHandler; +>onChangeCapture : Symbol(DOMAttributes.onChangeCapture, Decl(index.d.ts, 31, 39)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInput?: FormEventHandler; +>onInput : Symbol(DOMAttributes.onInput, Decl(index.d.ts, 32, 46)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInputCapture?: FormEventHandler; +>onInputCapture : Symbol(DOMAttributes.onInputCapture, Decl(index.d.ts, 33, 38)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onReset?: FormEventHandler; +>onReset : Symbol(DOMAttributes.onReset, Decl(index.d.ts, 34, 45)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onResetCapture?: FormEventHandler; +>onResetCapture : Symbol(DOMAttributes.onResetCapture, Decl(index.d.ts, 35, 38)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onSubmit?: FormEventHandler; +>onSubmit : Symbol(DOMAttributes.onSubmit, Decl(index.d.ts, 36, 45)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onSubmitCapture?: FormEventHandler; +>onSubmitCapture : Symbol(DOMAttributes.onSubmitCapture, Decl(index.d.ts, 37, 39)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInvalid?: FormEventHandler; +>onInvalid : Symbol(DOMAttributes.onInvalid, Decl(index.d.ts, 38, 46)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInvalidCapture?: FormEventHandler; +>onInvalidCapture : Symbol(DOMAttributes.onInvalidCapture, Decl(index.d.ts, 39, 40)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + } + + interface HTMLAttributes extends DOMAttributes {} +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 43, 29)) +>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 28, 5)) +>T : Symbol(T, Decl(index.d.ts, 43, 29)) + + interface InputHTMLAttributes extends HTMLAttributes { +>InputHTMLAttributes : Symbol(InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) + + onChange?: ChangeEventHandler; +>onChange : Symbol(InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>ChangeEventHandler : Symbol(ChangeEventHandler, Decl(index.d.ts, 49, 58)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) + } + + type FormEventHandler = EventHandler>; +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 49, 26)) +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>FormEvent : Symbol(FormEvent, Decl(index.d.ts, 25, 5)) +>T : Symbol(T, Decl(index.d.ts, 49, 26)) + + type ChangeEventHandler = EventHandler>; +>ChangeEventHandler : Symbol(ChangeEventHandler, Decl(index.d.ts, 49, 58)) +>T : Symbol(T, Decl(index.d.ts, 50, 28)) +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>ChangeEvent : Symbol(ChangeEvent, Decl(index.d.ts, 21, 5)) +>T : Symbol(T, Decl(index.d.ts, 50, 28)) + + type EventHandler> = (event: E) => void; +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>E : Symbol(E, Decl(index.d.ts, 51, 22)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>event : Symbol(event, Decl(index.d.ts, 51, 56)) +>E : Symbol(E, Decl(index.d.ts, 51, 22)) + + type DetailedHTMLProps, T> = ClassAttributes & E; +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>E : Symbol(E, Decl(index.d.ts, 52, 27)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>E : Symbol(E, Decl(index.d.ts, 52, 27)) + + interface Attributes { +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) + + key?: Key; +>key : Symbol(Attributes.key, Decl(index.d.ts, 54, 26)) +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + } + interface ClassAttributes extends Attributes { +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 57, 30)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) + + ref?: Ref; +>ref : Symbol(ClassAttributes.ref, Decl(index.d.ts, 57, 53)) +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 57, 30)) + } + + type Key = string | number; +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + + type Ref = string | ((instance: T | null) => any); +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 62, 13)) +>instance : Symbol(instance, Decl(index.d.ts, 62, 29)) +>T : Symbol(T, Decl(index.d.ts, 62, 13)) + + interface Component

extends ComponentLifecycle {} +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 64, 24)) +>S : Symbol(S, Decl(index.d.ts, 64, 31)) +>ComponentLifecycle : Symbol(ComponentLifecycle, Decl(index.d.ts, 64, 75)) +>P : Symbol(P, Decl(index.d.ts, 64, 24)) +>S : Symbol(S, Decl(index.d.ts, 64, 31)) + + interface ComponentLifecycle { +>ComponentLifecycle : Symbol(ComponentLifecycle, Decl(index.d.ts, 64, 75)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) + + componentWillMount?(): void; +>componentWillMount : Symbol(ComponentLifecycle.componentWillMount, Decl(index.d.ts, 66, 40)) + + componentDidMount?(): void; +>componentDidMount : Symbol(ComponentLifecycle.componentDidMount, Decl(index.d.ts, 67, 36)) + + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; +>componentWillReceiveProps : Symbol(ComponentLifecycle.componentWillReceiveProps, Decl(index.d.ts, 68, 35)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 69, 35)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 69, 58)) + + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; +>shouldComponentUpdate : Symbol(ComponentLifecycle.shouldComponentUpdate, Decl(index.d.ts, 69, 83)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 70, 31)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextState : Symbol(nextState, Decl(index.d.ts, 70, 54)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 70, 78)) + + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; +>componentWillUpdate : Symbol(ComponentLifecycle.componentWillUpdate, Decl(index.d.ts, 70, 106)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 71, 29)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextState : Symbol(nextState, Decl(index.d.ts, 71, 52)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 71, 76)) + + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; +>componentDidUpdate : Symbol(ComponentLifecycle.componentDidUpdate, Decl(index.d.ts, 71, 101)) +>prevProps : Symbol(prevProps, Decl(index.d.ts, 72, 28)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>prevState : Symbol(prevState, Decl(index.d.ts, 72, 51)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>prevContext : Symbol(prevContext, Decl(index.d.ts, 72, 75)) + + componentWillUnmount?(): void; +>componentWillUnmount : Symbol(ComponentLifecycle.componentWillUnmount, Decl(index.d.ts, 72, 100)) + + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; +>componentDidCatch : Symbol(ComponentLifecycle.componentDidCatch, Decl(index.d.ts, 73, 38)) +>error : Symbol(error, Decl(index.d.ts, 74, 27)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>errorInfo : Symbol(errorInfo, Decl(index.d.ts, 74, 40)) +>ErrorInfo : Symbol(ErrorInfo, Decl(index.d.ts, 75, 5)) + } + + interface ErrorInfo { +>ErrorInfo : Symbol(ErrorInfo, Decl(index.d.ts, 75, 5)) + + componentStack: string; +>componentStack : Symbol(ErrorInfo.componentStack, Decl(index.d.ts, 77, 25)) + } + + interface ReactElement

{ +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + type: string | ComponentClass

| SFC

; +>type : Symbol(ReactElement.type, Decl(index.d.ts, 81, 31)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + props: P; +>props : Symbol(ReactElement.props, Decl(index.d.ts, 82, 50)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + key: Key | null; +>key : Symbol(ReactElement.key, Decl(index.d.ts, 83, 17)) +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + } + + interface SFCElement

extends ReactElement

{ +>SFCElement : Symbol(SFCElement, Decl(index.d.ts, 85, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) + + type: SFC

; +>type : Symbol(SFCElement.type, Decl(index.d.ts, 87, 53)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) + } + + type ComponentState = {}; +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + type ClassType, C extends ComponentClass

> = +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>T : Symbol(T, Decl(index.d.ts, 92, 21)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>C : Symbol(C, Decl(index.d.ts, 92, 61)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) + + & C +>C : Symbol(C, Decl(index.d.ts, 92, 61)) + + & (new (props?: P, context?: any) => T) +>props : Symbol(props, Decl(index.d.ts, 94, 16)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>context : Symbol(context, Decl(index.d.ts, 94, 26)) +>T : Symbol(T, Decl(index.d.ts, 92, 21)) + + & (new (props?: P, context?: any) => { props: P }); +>props : Symbol(props, Decl(index.d.ts, 95, 16)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>context : Symbol(context, Decl(index.d.ts, 95, 26)) +>props : Symbol(props, Decl(index.d.ts, 95, 46)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) + + type CElement> = ComponentElement; +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>T : Symbol(T, Decl(index.d.ts, 97, 20)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ComponentElement : Symbol(ComponentElement, Decl(index.d.ts, 97, 86)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>T : Symbol(T, Decl(index.d.ts, 97, 20)) + + interface ComponentElement> extends ReactElement

{ +>ComponentElement : Symbol(ComponentElement, Decl(index.d.ts, 97, 86)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) +>T : Symbol(T, Decl(index.d.ts, 98, 33)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) + + type: ComponentClass

; +>type : Symbol(ComponentElement.type, Decl(index.d.ts, 98, 99)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) + + ref?: Ref; +>ref : Symbol(ComponentElement.ref, Decl(index.d.ts, 99, 32)) +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 98, 33)) + } + + interface ClassicComponent

extends Component { +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 103, 31)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 103, 31)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) + + replaceState(nextState: S, callback?: () => any): void; +>replaceState : Symbol(ClassicComponent.replaceState, Decl(index.d.ts, 103, 72)) +>nextState : Symbol(nextState, Decl(index.d.ts, 104, 21)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) +>callback : Symbol(callback, Decl(index.d.ts, 104, 34)) + + isMounted(): boolean; +>isMounted : Symbol(ClassicComponent.isMounted, Decl(index.d.ts, 104, 63)) + + getInitialState?(): S; +>getInitialState : Symbol(ClassicComponent.getInitialState, Decl(index.d.ts, 105, 29)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) + } + + interface ClassicComponentClass

extends ComponentClass

{ +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(index.d.ts, 107, 5)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) + + new (props?: P, context?: any): ClassicComponent; +>props : Symbol(props, Decl(index.d.ts, 110, 13)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>context : Symbol(context, Decl(index.d.ts, 110, 23)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + getDefaultProps?(): P; +>getDefaultProps : Symbol(ClassicComponentClass.getDefaultProps, Decl(index.d.ts, 110, 76)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) + } + + type SFC

= StatelessComponent

; +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 114, 13)) +>StatelessComponent : Symbol(StatelessComponent, Decl(index.d.ts, 114, 45)) +>P : Symbol(P, Decl(index.d.ts, 114, 13)) + + interface StatelessComponent

{ +>StatelessComponent : Symbol(StatelessComponent, Decl(index.d.ts, 114, 45)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; +>props : Symbol(props, Decl(index.d.ts, 116, 9)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) +>children : Symbol(children, Decl(index.d.ts, 116, 21)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>context : Symbol(context, Decl(index.d.ts, 116, 45)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) + + propTypes?: ValidationMap

; +>propTypes : Symbol(StatelessComponent.propTypes, Decl(index.d.ts, 116, 87)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + contextTypes?: ValidationMap; +>contextTypes : Symbol(StatelessComponent.contextTypes, Decl(index.d.ts, 117, 37)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + defaultProps?: Partial

; +>defaultProps : Symbol(StatelessComponent.defaultProps, Decl(index.d.ts, 118, 42)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + displayName?: string; +>displayName : Symbol(StatelessComponent.displayName, Decl(index.d.ts, 119, 34)) + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) +>ReactFragment : Symbol(ReactFragment, Decl(index.d.ts, 125, 37)) + + type ReactChild = ReactElement | ReactText; +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>ReactText : Symbol(ReactText, Decl(index.d.ts, 124, 52)) + + type ReactText = string | number; +>ReactText : Symbol(ReactText, Decl(index.d.ts, 124, 52)) + + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; +>ReactFragment : Symbol(ReactFragment, Decl(index.d.ts, 125, 37)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) + + interface ComponentClass

{ +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + new (props?: P, context?: any): Component; +>props : Symbol(props, Decl(index.d.ts, 130, 13)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) +>context : Symbol(context, Decl(index.d.ts, 130, 23)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + propTypes?: ValidationMap

; +>propTypes : Symbol(ComponentClass.propTypes, Decl(index.d.ts, 130, 57)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + contextTypes?: ValidationMap; +>contextTypes : Symbol(ComponentClass.contextTypes, Decl(index.d.ts, 131, 37)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + childContextTypes?: ValidationMap; +>childContextTypes : Symbol(ComponentClass.childContextTypes, Decl(index.d.ts, 132, 42)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + defaultProps?: Partial

; +>defaultProps : Symbol(ComponentClass.defaultProps, Decl(index.d.ts, 133, 47)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + displayName?: string; +>displayName : Symbol(ComponentClass.displayName, Decl(index.d.ts, 134, 34)) + } + + type ValidationMap = {[K in keyof T]?: Validator }; +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) +>K : Symbol(K, Decl(index.d.ts, 138, 30)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) +>Validator : Symbol(Validator, Decl(index.d.ts, 138, 61)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) + + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; +>Validator : Symbol(Validator, Decl(index.d.ts, 138, 61)) +>T : Symbol(T, Decl(index.d.ts, 139, 19)) +>object : Symbol(object, Decl(index.d.ts, 139, 25)) +>T : Symbol(T, Decl(index.d.ts, 139, 19)) +>key : Symbol(key, Decl(index.d.ts, 139, 35)) +>componentName : Symbol(componentName, Decl(index.d.ts, 139, 48)) +>rest : Symbol(rest, Decl(index.d.ts, 139, 71)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + type: SFC

, +>type : Symbol(type, Decl(index.d.ts, 141, 30)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + props?: Attributes & P, +>props : Symbol(props, Decl(index.d.ts, 142, 21)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + ...children: ReactNode[]): SFCElement

; +>children : Symbol(children, Decl(index.d.ts, 143, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>SFCElement : Symbol(SFCElement, Decl(index.d.ts, 85, 5)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + type: ClassType, ClassicComponentClass

>, +>type : Symbol(type, Decl(index.d.ts, 145, 30)) +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(index.d.ts, 107, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + props?: ClassAttributes> & P, +>props : Symbol(props, Decl(index.d.ts, 146, 90)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + ...children: ReactNode[]): CElement>; +>children : Symbol(children, Decl(index.d.ts, 147, 73)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + function createElement, C extends ComponentClass

>( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>C : Symbol(C, Decl(index.d.ts, 149, 69)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) + + type: ClassType, +>type : Symbol(type, Decl(index.d.ts, 149, 99)) +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>C : Symbol(C, Decl(index.d.ts, 149, 69)) + + props?: ClassAttributes & P, +>props : Symbol(props, Decl(index.d.ts, 150, 33)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) + + ...children: ReactNode[]): CElement; +>children : Symbol(children, Decl(index.d.ts, 151, 39)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + type: ComponentClass

, +>type : Symbol(type, Decl(index.d.ts, 153, 30)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + props?: Attributes & P, +>props : Symbol(props, Decl(index.d.ts, 154, 32)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + ...children: ReactNode[]): ReactElement

; +>children : Symbol(children, Decl(index.d.ts, 155, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) +} + +declare global { +>global : Symbol(global, Decl(index.d.ts, 157, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(index.d.ts, 159, 16)) + + interface Element extends React.ReactElement {} +>Element : Symbol(Element, Decl(index.d.ts, 160, 19)) +>React.ReactElement : Symbol(React.ReactElement, Decl(index.d.ts, 79, 5)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>ReactElement : Symbol(React.ReactElement, Decl(index.d.ts, 79, 5)) + + interface ElementClass extends React.Component { +>ElementClass : Symbol(ElementClass, Decl(index.d.ts, 161, 60)) +>React.Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) + + render(): JSX.Element | null | false; +>render : Symbol(ElementClass.render, Decl(index.d.ts, 162, 61)) +>JSX : Symbol(JSX, Decl(index.d.ts, 159, 16)) +>Element : Symbol(Element, Decl(index.d.ts, 160, 19)) + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(index.d.ts, 164, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(index.d.ts, 165, 45)) + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(index.d.ts, 165, 58)) +>children : Symbol(ElementChildrenAttribute.children, Decl(index.d.ts, 166, 44)) + + interface IntrinsicAttributes extends React.Attributes {} +>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(index.d.ts, 166, 60)) +>React.Attributes : Symbol(React.Attributes, Decl(index.d.ts, 52, 84)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>Attributes : Symbol(React.Attributes, Decl(index.d.ts, 52, 84)) + + interface IntrinsicClassAttributes extends React.ClassAttributes {} +>IntrinsicClassAttributes : Symbol(IntrinsicClassAttributes, Decl(index.d.ts, 168, 65)) +>T : Symbol(T, Decl(index.d.ts, 169, 43)) +>React.ClassAttributes : Symbol(React.ClassAttributes, Decl(index.d.ts, 56, 5)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>ClassAttributes : Symbol(React.ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 169, 43)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 169, 81)) + + input: React.DetailedHTMLProps, HTMLInputElement>; +>input : Symbol(IntrinsicElements.input, Decl(index.d.ts, 171, 37)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>InputHTMLAttributes : Symbol(React.InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + } + } +} + diff --git a/tests/baselines/reference/tsxRefInference.types b/tests/baselines/reference/tsxRefInference.types new file mode 100644 index 0000000000000..6a83641ebc1a6 --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.types @@ -0,0 +1,810 @@ +=== tests/cases/compiler/index.tsx === +import React = require("react"); +>React : typeof React + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { +>MyInputProps : MyInputProps +>React.DetailedHTMLProps : any +>React : typeof React +>DetailedHTMLProps : React.DetailedHTMLProps +>React : any +>InputHTMLAttributes : React.InputHTMLAttributes +>HTMLInputElement : HTMLInputElement +>HTMLInputElement : HTMLInputElement + + onValid?(): boolean; +>onValid : () => boolean + + onInvalid?(): boolean; +>onInvalid : () => boolean +} + +class MyInput implements React.Component { +>MyInput : MyInput +>React.Component : any +>React : typeof React +>Component : React.Component +>MyInputProps : MyInputProps + + props: MyInputProps; +>props : MyInputProps +>MyInputProps : MyInputProps + + render() { +>render : () => JSX.Element + + const { onValid, onInvalid, onChange, ...inputProps } = this.props; +>onValid : () => boolean +>onInvalid : () => boolean +>onChange : React.EventHandler> +>inputProps : { ref?: React.Ref; key?: string | number; onChangeCapture?: React.EventHandler>; onInput?: React.EventHandler>; onInputCapture?: React.EventHandler>; onReset?: React.EventHandler>; onResetCapture?: React.EventHandler>; onSubmit?: React.EventHandler>; onSubmitCapture?: React.EventHandler>; onInvalidCapture?: React.EventHandler>; } +>this.props : MyInputProps +>this : this +>props : MyInputProps + + return ( +>( ) : JSX.Element + + : JSX.Element +>input : any + + { ...inputProps } +>inputProps : { ref?: React.Ref; key?: string | number; onChangeCapture?: React.EventHandler>; onInput?: React.EventHandler>; onInputCapture?: React.EventHandler>; onReset?: React.EventHandler>; onResetCapture?: React.EventHandler>; onSubmit?: React.EventHandler>; onSubmitCapture?: React.EventHandler>; onInvalidCapture?: React.EventHandler>; } + + onChange={ this._onChange } +>onChange : (event: React.ChangeEvent) => void +>this._onChange : (event: React.ChangeEvent) => void +>this : this +>_onChange : (event: React.ChangeEvent) => void + + /> + ); + } + + componentDidMount() {} +>componentDidMount : () => void + + private _onChange(event: React.ChangeEvent) { +>_onChange : (event: React.ChangeEvent) => void +>event : React.ChangeEvent +>React : any +>ChangeEvent : React.ChangeEvent +>HTMLInputElement : HTMLInputElement + + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { +>this.props.onChange : React.EventHandler> +>this.props : MyInputProps +>this : this +>props : MyInputProps +>onChange : React.EventHandler> + + this.props.onChange(event); +>this.props.onChange(event) : void +>this.props.onChange : React.EventHandler> +>this.props : MyInputProps +>this : this +>props : MyInputProps +>onChange : React.EventHandler> +>event : React.ChangeEvent + } + } +} + +function someFunction() {} +>someFunction : () => void + +const x = 0} onChange={someFunction} />; +>x : JSX.Element +> 0} onChange={someFunction} /> : JSX.Element +>MyInput : typeof MyInput +>ref : (r: HTMLInputElement | MyInput) => number +>r => 0 : (r: HTMLInputElement | MyInput) => number +>r : HTMLInputElement | MyInput +>0 : 0 +>onChange : () => void +>someFunction : () => void + +=== tests/cases/compiler/node_modules/react/index.d.ts === +export as namespace React; +>React : typeof React + +export = React; +>React : typeof React + +declare namespace React { +>React : typeof React + + interface SyntheticEvent { +>SyntheticEvent : SyntheticEvent +>T : T + + bubbles: boolean; +>bubbles : boolean + + currentTarget: EventTarget & T; +>currentTarget : EventTarget & T +>EventTarget : EventTarget +>T : T + + cancelable: boolean; +>cancelable : boolean + + defaultPrevented: boolean; +>defaultPrevented : boolean + + eventPhase: number; +>eventPhase : number + + isTrusted: boolean; +>isTrusted : boolean + + nativeEvent: Event; +>nativeEvent : Event +>Event : Event + + preventDefault(): void; +>preventDefault : () => void + + isDefaultPrevented(): boolean; +>isDefaultPrevented : () => boolean + + stopPropagation(): void; +>stopPropagation : () => void + + isPropagationStopped(): boolean; +>isPropagationStopped : () => boolean + + persist(): void; +>persist : () => void + + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; +>target : EventTarget +>EventTarget : EventTarget + + timeStamp: number; +>timeStamp : number + + type: string; +>type : string + } + + interface ChangeEvent extends SyntheticEvent { +>ChangeEvent : ChangeEvent +>T : T +>SyntheticEvent : SyntheticEvent +>T : T + + target: EventTarget & T; +>target : EventTarget & T +>EventTarget : EventTarget +>T : T + } + + interface FormEvent extends SyntheticEvent { +>FormEvent : FormEvent +>T : T +>SyntheticEvent : SyntheticEvent +>T : T + } + + interface DOMAttributes { +>DOMAttributes : DOMAttributes +>T : T + + onChange?: FormEventHandler; +>onChange : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onChangeCapture?: FormEventHandler; +>onChangeCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInput?: FormEventHandler; +>onInput : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInputCapture?: FormEventHandler; +>onInputCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onReset?: FormEventHandler; +>onReset : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onResetCapture?: FormEventHandler; +>onResetCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onSubmit?: FormEventHandler; +>onSubmit : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onSubmitCapture?: FormEventHandler; +>onSubmitCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInvalid?: FormEventHandler; +>onInvalid : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInvalidCapture?: FormEventHandler; +>onInvalidCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + } + + interface HTMLAttributes extends DOMAttributes {} +>HTMLAttributes : HTMLAttributes +>T : T +>DOMAttributes : DOMAttributes +>T : T + + interface InputHTMLAttributes extends HTMLAttributes { +>InputHTMLAttributes : InputHTMLAttributes +>T : T +>HTMLAttributes : HTMLAttributes +>T : T + + onChange?: ChangeEventHandler; +>onChange : (event: ChangeEvent) => void +>ChangeEventHandler : (event: ChangeEvent) => void +>T : T + } + + type FormEventHandler = EventHandler>; +>FormEventHandler : (event: FormEvent) => void +>T : T +>EventHandler : (event: E) => void +>FormEvent : FormEvent +>T : T + + type ChangeEventHandler = EventHandler>; +>ChangeEventHandler : (event: ChangeEvent) => void +>T : T +>EventHandler : (event: E) => void +>ChangeEvent : ChangeEvent +>T : T + + type EventHandler> = (event: E) => void; +>EventHandler : (event: E) => void +>E : E +>SyntheticEvent : SyntheticEvent +>event : E +>E : E + + type DetailedHTMLProps, T> = ClassAttributes & E; +>DetailedHTMLProps : ClassAttributes & E +>E : E +>HTMLAttributes : HTMLAttributes +>T : T +>T : T +>ClassAttributes : ClassAttributes +>T : T +>E : E + + interface Attributes { +>Attributes : Attributes + + key?: Key; +>key : string | number +>Key : string | number + } + interface ClassAttributes extends Attributes { +>ClassAttributes : ClassAttributes +>T : T +>Attributes : Attributes + + ref?: Ref; +>ref : string | ((instance: T) => any) +>Ref : string | ((instance: T) => any) +>T : T + } + + type Key = string | number; +>Key : string | number + + type Ref = string | ((instance: T | null) => any); +>Ref : string | ((instance: T) => any) +>T : T +>instance : T +>T : T +>null : null + + interface Component

extends ComponentLifecycle {} +>Component : Component +>P : P +>S : S +>ComponentLifecycle : ComponentLifecycle +>P : P +>S : S + + interface ComponentLifecycle { +>ComponentLifecycle : ComponentLifecycle +>P : P +>S : S + + componentWillMount?(): void; +>componentWillMount : () => void + + componentDidMount?(): void; +>componentDidMount : () => void + + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; +>componentWillReceiveProps : (nextProps: Readonly

, nextContext: any) => void +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextContext : any + + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; +>shouldComponentUpdate : (nextProps: Readonly

, nextState: Readonly, nextContext: any) => boolean +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextState : Readonly +>Readonly : Readonly +>S : S +>nextContext : any + + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; +>componentWillUpdate : (nextProps: Readonly

, nextState: Readonly, nextContext: any) => void +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextState : Readonly +>Readonly : Readonly +>S : S +>nextContext : any + + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; +>componentDidUpdate : (prevProps: Readonly

, prevState: Readonly, prevContext: any) => void +>prevProps : Readonly

+>Readonly : Readonly +>P : P +>prevState : Readonly +>Readonly : Readonly +>S : S +>prevContext : any + + componentWillUnmount?(): void; +>componentWillUnmount : () => void + + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; +>componentDidCatch : (error: Error, errorInfo: ErrorInfo) => void +>error : Error +>Error : Error +>errorInfo : ErrorInfo +>ErrorInfo : ErrorInfo + } + + interface ErrorInfo { +>ErrorInfo : ErrorInfo + + componentStack: string; +>componentStack : string + } + + interface ReactElement

{ +>ReactElement : ReactElement

+>P : P + + type: string | ComponentClass

| SFC

; +>type : string | ComponentClass

| StatelessComponent

+>ComponentClass : ComponentClass

+>P : P +>SFC : StatelessComponent

+>P : P + + props: P; +>props : P +>P : P + + key: Key | null; +>key : string | number +>Key : string | number +>null : null + } + + interface SFCElement

extends ReactElement

{ +>SFCElement : SFCElement

+>P : P +>ReactElement : ReactElement

+>P : P + + type: SFC

; +>type : StatelessComponent

+>SFC : StatelessComponent

+>P : P + } + + type ComponentState = {}; +>ComponentState : {} + + type ClassType, C extends ComponentClass

> = +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>C : C +>ComponentClass : ComponentClass

+>P : P + + & C +>C : C + + & (new (props?: P, context?: any) => T) +>props : P +>P : P +>context : any +>T : T + + & (new (props?: P, context?: any) => { props: P }); +>props : P +>P : P +>context : any +>props : P +>P : P + + type CElement> = ComponentElement; +>CElement : ComponentElement +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>ComponentElement : ComponentElement +>P : P +>T : T + + interface ComponentElement> extends ReactElement

{ +>ComponentElement : ComponentElement +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>ReactElement : ReactElement

+>P : P + + type: ComponentClass

; +>type : ComponentClass

+>ComponentClass : ComponentClass

+>P : P + + ref?: Ref; +>ref : string | ((instance: T) => any) +>Ref : string | ((instance: T) => any) +>T : T + } + + interface ClassicComponent

extends Component { +>ClassicComponent : ClassicComponent +>P : P +>S : S +>Component : Component +>P : P +>S : S + + replaceState(nextState: S, callback?: () => any): void; +>replaceState : (nextState: S, callback?: () => any) => void +>nextState : S +>S : S +>callback : () => any + + isMounted(): boolean; +>isMounted : () => boolean + + getInitialState?(): S; +>getInitialState : () => S +>S : S + } + + interface ClassicComponentClass

extends ComponentClass

{ +>ClassicComponentClass : ClassicComponentClass

+>P : P +>ComponentClass : ComponentClass

+>P : P + + new (props?: P, context?: any): ClassicComponent; +>props : P +>P : P +>context : any +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} + + getDefaultProps?(): P; +>getDefaultProps : () => P +>P : P + } + + type SFC

= StatelessComponent

; +>SFC : StatelessComponent

+>P : P +>StatelessComponent : StatelessComponent

+>P : P + + interface StatelessComponent

{ +>StatelessComponent : StatelessComponent

+>P : P + + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; +>props : P & { children?: string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[]; } +>P : P +>children : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>context : any +>ReactElement : ReactElement

+>null : null + + propTypes?: ValidationMap

; +>propTypes : { [K in keyof T]?: (object: P, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>P : P + + contextTypes?: ValidationMap; +>contextTypes : { [x: string]: (object: any, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + defaultProps?: Partial

; +>defaultProps : Partial

+>Partial : Partial +>P : P + + displayName?: string; +>displayName : string + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactChild : string | number | ReactElement +>ReactFragment : {} | (string | number | boolean | any[] | ReactElement)[] +>null : null + + type ReactChild = ReactElement | ReactText; +>ReactChild : string | number | ReactElement +>ReactElement : ReactElement

+>ReactText : string | number + + type ReactText = string | number; +>ReactText : string | number + + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; +>ReactFragment : {} | (string | number | boolean | any[] | ReactElement)[] +>Array : T[] +>ReactChild : string | number | ReactElement + + interface ComponentClass

{ +>ComponentClass : ComponentClass

+>P : P + + new (props?: P, context?: any): Component; +>props : P +>P : P +>context : any +>Component : Component +>P : P + + propTypes?: ValidationMap

; +>propTypes : { [K in keyof T]?: (object: P, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>P : P + + contextTypes?: ValidationMap; +>contextTypes : { [x: string]: (object: any, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + childContextTypes?: ValidationMap; +>childContextTypes : { [x: string]: (object: any, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + defaultProps?: Partial

; +>defaultProps : Partial

+>Partial : Partial +>P : P + + displayName?: string; +>displayName : string + } + + type ValidationMap = {[K in keyof T]?: Validator }; +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>T : T +>K : K +>T : T +>Validator : (object: T, key: string, componentName: string, ...rest: any[]) => Error +>T : T + + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; +>Validator : (object: T, key: string, componentName: string, ...rest: any[]) => Error +>T : T +>object : T +>T : T +>key : string +>componentName : string +>rest : any[] +>Error : Error +>null : null + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: SFC

, +>type : StatelessComponent

+>SFC : StatelessComponent

+>P : P + + props?: Attributes & P, +>props : Attributes & P +>Attributes : Attributes +>P : P + + ...children: ReactNode[]): SFCElement

; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>SFCElement : SFCElement

+>P : P + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: ClassType, ClassicComponentClass

>, +>type : ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }) +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} +>ClassicComponentClass : ClassicComponentClass

+>P : P + + props?: ClassAttributes> & P, +>props : ClassAttributes> & P +>ClassAttributes : ClassAttributes +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} +>P : P + + ...children: ReactNode[]): CElement>; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>CElement : ComponentElement +>P : P +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} + + function createElement, C extends ComponentClass

>( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>C : C +>ComponentClass : ComponentClass

+>P : P + + type: ClassType, +>type : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>T : T +>C : C + + props?: ClassAttributes & P, +>props : ClassAttributes & P +>ClassAttributes : ClassAttributes +>T : T +>P : P + + ...children: ReactNode[]): CElement; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>CElement : ComponentElement +>P : P +>T : T + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: ComponentClass

, +>type : ComponentClass

+>ComponentClass : ComponentClass

+>P : P + + props?: Attributes & P, +>props : Attributes & P +>Attributes : Attributes +>P : P + + ...children: ReactNode[]): ReactElement

; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactElement : ReactElement

+>P : P +} + +declare global { +>global : any + + namespace JSX { +>JSX : any + + interface Element extends React.ReactElement {} +>Element : Element +>React.ReactElement : any +>React : typeof React +>ReactElement : React.ReactElement

+ + interface ElementClass extends React.Component { +>ElementClass : ElementClass +>React.Component : any +>React : typeof React +>Component : React.Component + + render(): JSX.Element | null | false; +>render : () => false | Element +>JSX : any +>Element : Element +>null : null +>false : false + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : ElementAttributesProperty +>props : {} + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : {} + + interface IntrinsicAttributes extends React.Attributes {} +>IntrinsicAttributes : IntrinsicAttributes +>React.Attributes : any +>React : typeof React +>Attributes : React.Attributes + + interface IntrinsicClassAttributes extends React.ClassAttributes {} +>IntrinsicClassAttributes : IntrinsicClassAttributes +>T : T +>React.ClassAttributes : any +>React : typeof React +>ClassAttributes : React.ClassAttributes +>T : T + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + input: React.DetailedHTMLProps, HTMLInputElement>; +>input : React.ClassAttributes & React.InputHTMLAttributes +>React : any +>DetailedHTMLProps : React.ClassAttributes & E +>React : any +>InputHTMLAttributes : React.InputHTMLAttributes +>HTMLInputElement : HTMLInputElement +>HTMLInputElement : HTMLInputElement + } + } +} + diff --git a/tests/cases/compiler/restParameterContextualTypes.ts b/tests/cases/compiler/restParameterContextualTypes.ts new file mode 100644 index 0000000000000..a1c673f781a7f --- /dev/null +++ b/tests/cases/compiler/restParameterContextualTypes.ts @@ -0,0 +1,16 @@ +// @strictNullChecks: true +type ComplexCalls = { + (): string; + (a: number): string; + (a: {x: number}, b: string): string; + (a: symbol, ...rest: {y: string}[]): string; + (...rest: {z: string}[]): string; +}; + +const x: ComplexCalls = (...rest) => rest.toString(); + +const y: ComplexCalls = (_a = 1, ...rest) => rest.toString(); + +const z: ComplexCalls = (_a = 1, _b = "", ...rest) => rest.toString(); + +const more: ComplexCalls = (_a = 1, _b = "", _c = { z: "" }, ...rest) => rest.toString(); diff --git a/tests/cases/compiler/tsxRefInference.tsx b/tests/cases/compiler/tsxRefInference.tsx new file mode 100644 index 0000000000000..44d5f662dc4b8 --- /dev/null +++ b/tests/cases/compiler/tsxRefInference.tsx @@ -0,0 +1,216 @@ +// @jsx: react +// @moduleResolution: node +// @noImplicitAny: true +// @lib: dom,es6 +// @filename: node_modules/react/index.d.ts +export as namespace React; +export = React; + +declare namespace React { + interface SyntheticEvent { + bubbles: boolean; + currentTarget: EventTarget & T; + cancelable: boolean; + defaultPrevented: boolean; + eventPhase: number; + isTrusted: boolean; + nativeEvent: Event; + preventDefault(): void; + isDefaultPrevented(): boolean; + stopPropagation(): void; + isPropagationStopped(): boolean; + persist(): void; + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; + timeStamp: number; + type: string; + } + + interface ChangeEvent extends SyntheticEvent { + target: EventTarget & T; + } + + interface FormEvent extends SyntheticEvent { + } + + interface DOMAttributes { + onChange?: FormEventHandler; + onChangeCapture?: FormEventHandler; + onInput?: FormEventHandler; + onInputCapture?: FormEventHandler; + onReset?: FormEventHandler; + onResetCapture?: FormEventHandler; + onSubmit?: FormEventHandler; + onSubmitCapture?: FormEventHandler; + onInvalid?: FormEventHandler; + onInvalidCapture?: FormEventHandler; + } + + interface HTMLAttributes extends DOMAttributes {} + + interface InputHTMLAttributes extends HTMLAttributes { + onChange?: ChangeEventHandler; + } + + type FormEventHandler = EventHandler>; + type ChangeEventHandler = EventHandler>; + type EventHandler> = (event: E) => void; + type DetailedHTMLProps, T> = ClassAttributes & E; + + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + type Key = string | number; + type Ref = string | ((instance: T | null) => any); + + interface Component

extends ComponentLifecycle {} + + interface ComponentLifecycle { + componentWillMount?(): void; + componentDidMount?(): void; + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; + componentWillUnmount?(): void; + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; + } + + interface ErrorInfo { + componentStack: string; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; + props: P; + key: Key | null; + } + + interface SFCElement

extends ReactElement

{ + type: SFC

; + } + + type ComponentState = {}; + type ClassType, C extends ComponentClass

> = + & C + & (new (props?: P, context?: any) => T) + & (new (props?: P, context?: any) => { props: P }); + + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; + } + + interface ClassicComponent

extends Component { + replaceState(nextState: S, callback?: () => any): void; + isMounted(): boolean; + getInitialState?(): S; + } + + interface ClassicComponentClass

extends ComponentClass

{ + new (props?: P, context?: any): ClassicComponent; + getDefaultProps?(): P; + } + + type SFC

= StatelessComponent

; + interface StatelessComponent

{ + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactChild = ReactElement | ReactText; + type ReactText = string | number; + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; + + interface ComponentClass

{ + new (props?: P, context?: any): Component; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + childContextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ValidationMap = {[K in keyof T]?: Validator }; + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; + + function createElement

( + type: SFC

, + props?: Attributes & P, + ...children: ReactNode[]): SFCElement

; + function createElement

( + type: ClassType, ClassicComponentClass

>, + props?: ClassAttributes> & P, + ...children: ReactNode[]): CElement>; + function createElement, C extends ComponentClass

>( + type: ClassType, + props?: ClassAttributes & P, + ...children: ReactNode[]): CElement; + function createElement

( + type: ComponentClass

, + props?: Attributes & P, + ...children: ReactNode[]): ReactElement

; +} + +declare global { + namespace JSX { + interface Element extends React.ReactElement {} + interface ElementClass extends React.Component { + render(): JSX.Element | null | false; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + + interface IntrinsicAttributes extends React.Attributes {} + interface IntrinsicClassAttributes extends React.ClassAttributes {} + + interface IntrinsicElements { + input: React.DetailedHTMLProps, HTMLInputElement>; + } + } +} + +// @filename: index.tsx +import React = require("react"); + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { + onValid?(): boolean; + onInvalid?(): boolean; +} + +class MyInput implements React.Component { + props: MyInputProps; + render() { + const { onValid, onInvalid, onChange, ...inputProps } = this.props; + return ( + + ); + } + + componentDidMount() {} + + private _onChange(event: React.ChangeEvent) { + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + } +} + +function someFunction() {} +const x = 0} onChange={someFunction} />; \ No newline at end of file