diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3377ae96b0ded..23c5568f2e5f4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6799,7 +6799,12 @@ namespace ts { // type is the union of the constituent return types. function getUnionSignatures(signatureLists: ReadonlyArray>): Signature[] { let result: Signature[] | undefined; + let indexWithLengthOverOne: number | undefined; for (let i = 0; i < signatureLists.length; i++) { + if (signatureLists[i].length === 0) return emptyArray; + if (signatureLists[i].length > 1) { + indexWithLengthOverOne = indexWithLengthOverOne === undefined ? i : -1; // -1 is a signal there are multiple overload sets + } for (const signature of signatureLists[i]) { // Only process signatures with parameter lists that aren't already in the result list if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) { @@ -6823,9 +6828,91 @@ namespace ts { } } } + if (!length(result) && indexWithLengthOverOne !== -1) { + // No sufficiently similar signature existed to subsume all the other signatures in the union - time to see if we can make a single + // signature that handles all over them. We only do this when there are overloads in only one constituent. + // (Overloads are conditional in nature and having overloads in multiple constituents would necessitate making a power set of + // signatures from the type, whose ordering would be non-obvious) + const masterList = signatureLists[indexWithLengthOverOne !== undefined ? indexWithLengthOverOne : 0]; + let results: Signature[] | undefined = masterList.slice(); + for (const signatures of signatureLists) { + if (signatures !== masterList) { + const signature = signatures[0]; + Debug.assert(!!signature, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass"); + results = signature.typeParameters && some(results, s => !!s.typeParameters) ? undefined : map(results, sig => combineSignaturesOfUnionMembers(sig, signature)); + if (!results) { + break; + } + } + } + result = results; + } return result || emptyArray; } + function combineUnionThisParam(left: Symbol | undefined, right: Symbol | undefined): Symbol | undefined { + if (!left || !right) { + return left || right; + } + // A signature `this` type might be a read or a write position... It's very possible that it should be invariant + // and we should refuse to merge signatures if there are `this` types and they do not match. However, so as to be + // permissive when calling, for now, we'll union the `this` types just like the overlapping-union-signature check does + const thisType = getUnionType([getTypeOfSymbol(left), getTypeOfSymbol(right)], UnionReduction.Subtype); + return createSymbolWithType(left, thisType); + } + + function combineUnionParameters(left: Signature, right: Signature) { + const longest = getParameterCount(left) >= getParameterCount(right) ? left : right; + const shorter = longest === left ? right : left; + const longestCount = getParameterCount(longest); + const eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right)); + const needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest); + const params = new Array(longestCount + (needsExtraRestElement ? 1 : 0)); + for (let i = 0; i < longestCount; i++) { + const longestParamType = tryGetTypeAtPosition(longest, i)!; + const shorterParamType = tryGetTypeAtPosition(shorter, i) || unknownType; + const unionParamType = getIntersectionType([longestParamType, shorterParamType]); + const isRestParam = eitherHasEffectiveRest && !needsExtraRestElement && i === (longestCount - 1); + const isOptional = i >= getMinArgumentCount(longest) && i >= getMinArgumentCount(shorter); + const leftName = getParameterNameAtPosition(left, i); + const rightName = getParameterNameAtPosition(right, i); + const paramSymbol = createSymbol( + SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0), + leftName === rightName ? leftName : `arg${i}` as __String + ); + paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType; + params[i] = paramSymbol; + } + if (needsExtraRestElement) { + const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String); + restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount)); + params[longestCount] = restParamSymbol; + } + return params; + } + + function combineSignaturesOfUnionMembers(left: Signature, right: Signature): Signature { + const declaration = left.declaration; + const params = combineUnionParameters(left, right); + const thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter); + const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount); + const hasRestParam = left.hasRestParameter || right.hasRestParameter; + const hasLiteralTypes = left.hasLiteralTypes || right.hasLiteralTypes; + const result = createSignature( + declaration, + left.typeParameters || right.typeParameters, + thisParam, + params, + /*resolvedReturnType*/ undefined, + /*resolvedTypePredicate*/ undefined, + minArgCount, + hasRestParam, + hasLiteralTypes + ); + result.unionSignatures = concatenate(left.unionSignatures || [left], [right]); + return result; + } + function getUnionIndexInfo(types: ReadonlyArray, kind: IndexKind): IndexInfo | undefined { const indexTypes: Type[] = []; let isAnyReadonly = false; @@ -17566,6 +17653,26 @@ namespace ts { } function getJsxPropsTypeForSignatureFromMember(sig: Signature, forcedLookupLocation: __String) { + if (sig.unionSignatures) { + // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input + // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature, + // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur + // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input. + // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane. + const results: Type[] = []; + for (const signature of sig.unionSignatures) { + const instance = getReturnTypeOfSignature(signature); + if (isTypeAny(instance)) { + return instance; + } + const propType = getTypeOfPropertyOfType(instance, forcedLookupLocation); + if (!propType) { + return; + } + results.push(propType); + } + return getIntersectionType(results); + } const instanceType = getReturnTypeOfSignature(sig); return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation); } diff --git a/tests/baselines/reference/callsOnComplexSignatures.errors.txt b/tests/baselines/reference/callsOnComplexSignatures.errors.txt new file mode 100644 index 0000000000000..f85a23e4ae79d --- /dev/null +++ b/tests/baselines/reference/callsOnComplexSignatures.errors.txt @@ -0,0 +1,110 @@ +tests/cases/compiler/callsOnComplexSignatures.tsx(38,19): error TS7006: Parameter 'item' implicitly has an 'any' type. + + +==== tests/cases/compiler/callsOnComplexSignatures.tsx (1 errors) ==== + /// + import React from "react"; + + // Simple calls from real usecases + function test1() { + type stringType1 = "foo" | "bar"; + type stringType2 = "baz" | "bar"; + + interface Temp1 { + getValue(name: stringType1): number; + } + + interface Temp2 { + getValue(name: stringType2): string; + } + + function test(t: Temp1 | Temp2) { + const z = t.getValue("bar"); // Should be fine + } + } + + function test2() { + interface Messages { + readonly foo: (options: { [key: string]: any, b: number }) => string; + readonly bar: (options: { [key: string]: any, a: string }) => string; + } + + const messages: Messages = { + foo: (options) => "Foo", + bar: (options) => "Bar", + }; + + const test1 = (type: "foo" | "bar") => + messages[type]({ a: "A", b: 0 }); + } + + function test3(items: string[] | number[]) { + items.forEach(item => console.log(item)); + ~~~~ +!!! error TS7006: Parameter 'item' implicitly has an 'any' type. + } + + function test4( + arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number), + arg2: ((a: {x: number}, b: object) => number) | ((a: object, b: {x: number}) => number), + arg3: ((a: {x: number}, ...objs: {y: number}[]) => number) | ((...objs: {x: number}[]) => number), + arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number), + arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number), + arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number), + ) { + arg1(); + arg1({x: 0, y: 0}); + arg1({x: 0, y: 0}, {x: 1, y: 1}); + + arg2({x: 0}, {x: 0}); + + arg3({x: 0}); + arg3({x: 0}, {x: 0, y: 0}); + arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}); + + arg4(); + arg4({x: 0, y: 0}); + arg4({x: 0, y: 0}, {x: 0}); + + arg5(); + arg5({x: 0, y: 0}); + arg5({x: 0, y: 0}, {x: 0}); + + arg6(); + arg6({x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}); + } + + // JSX Tag names + function test5() { + // Pair of non-like intrinsics + function render(url?: string): React.ReactNode { + const Tag = url ? 'a' : 'button'; + return test; + } + + // Union of all intrinsics and components of `any` + function App(props: { component:React.ReactType }) { + const Comp: React.ReactType = props.component; + return (); + } + + // custom components with non-subset props + function render2() { + interface P1 { + p?: boolean; + c?: string; + } + interface P2 { + p?: boolean; + c?: any; + d?: any; + } + + var C: React.ComponentType | React.ComponentType = null as any; + + const a = ; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/callsOnComplexSignatures.js b/tests/baselines/reference/callsOnComplexSignatures.js new file mode 100644 index 0000000000000..f631f674269cf --- /dev/null +++ b/tests/baselines/reference/callsOnComplexSignatures.js @@ -0,0 +1,169 @@ +//// [callsOnComplexSignatures.tsx] +/// +import React from "react"; + +// Simple calls from real usecases +function test1() { + type stringType1 = "foo" | "bar"; + type stringType2 = "baz" | "bar"; + + interface Temp1 { + getValue(name: stringType1): number; + } + + interface Temp2 { + getValue(name: stringType2): string; + } + + function test(t: Temp1 | Temp2) { + const z = t.getValue("bar"); // Should be fine + } +} + +function test2() { + interface Messages { + readonly foo: (options: { [key: string]: any, b: number }) => string; + readonly bar: (options: { [key: string]: any, a: string }) => string; + } + + const messages: Messages = { + foo: (options) => "Foo", + bar: (options) => "Bar", + }; + + const test1 = (type: "foo" | "bar") => + messages[type]({ a: "A", b: 0 }); +} + +function test3(items: string[] | number[]) { + items.forEach(item => console.log(item)); +} + +function test4( + arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number), + arg2: ((a: {x: number}, b: object) => number) | ((a: object, b: {x: number}) => number), + arg3: ((a: {x: number}, ...objs: {y: number}[]) => number) | ((...objs: {x: number}[]) => number), + arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number), + arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number), + arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number), +) { + arg1(); + arg1({x: 0, y: 0}); + arg1({x: 0, y: 0}, {x: 1, y: 1}); + + arg2({x: 0}, {x: 0}); + + arg3({x: 0}); + arg3({x: 0}, {x: 0, y: 0}); + arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}); + + arg4(); + arg4({x: 0, y: 0}); + arg4({x: 0, y: 0}, {x: 0}); + + arg5(); + arg5({x: 0, y: 0}); + arg5({x: 0, y: 0}, {x: 0}); + + arg6(); + arg6({x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}); +} + +// JSX Tag names +function test5() { + // Pair of non-like intrinsics + function render(url?: string): React.ReactNode { + const Tag = url ? 'a' : 'button'; + return test; + } + + // Union of all intrinsics and components of `any` + function App(props: { component:React.ReactType }) { + const Comp: React.ReactType = props.component; + return (); + } + + // custom components with non-subset props + function render2() { + interface P1 { + p?: boolean; + c?: string; + } + interface P2 { + p?: boolean; + c?: any; + d?: any; + } + + var C: React.ComponentType | React.ComponentType = null as any; + + const a = ; + } +} + + +//// [callsOnComplexSignatures.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +exports.__esModule = true; +/// +var react_1 = __importDefault(require("react")); +// Simple calls from real usecases +function test1() { + function test(t) { + var z = t.getValue("bar"); // Should be fine + } +} +function test2() { + var messages = { + foo: function (options) { return "Foo"; }, + bar: function (options) { return "Bar"; } + }; + var test1 = function (type) { + return messages[type]({ a: "A", b: 0 }); + }; +} +function test3(items) { + items.forEach(function (item) { return console.log(item); }); +} +function test4(arg1, arg2, arg3, arg4, arg5, arg6) { + arg1(); + arg1({ x: 0, y: 0 }); + arg1({ x: 0, y: 0 }, { x: 1, y: 1 }); + arg2({ x: 0 }, { x: 0 }); + arg3({ x: 0 }); + arg3({ x: 0 }, { x: 0, y: 0 }); + arg3({ x: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }); + arg4(); + arg4({ x: 0, y: 0 }); + arg4({ x: 0, y: 0 }, { x: 0 }); + arg5(); + arg5({ x: 0, y: 0 }); + arg5({ x: 0, y: 0 }, { x: 0 }); + arg6(); + arg6({ x: 0, y: 0 }); + arg6({ x: 0, y: 0 }, { x: 0, y: 0 }); + arg6({ x: 0, y: 0 }, { x: 0, y: 0 }, { y: 0 }); +} +// JSX Tag names +function test5() { + // Pair of non-like intrinsics + function render(url) { + var Tag = url ? 'a' : 'button'; + return react_1["default"].createElement(Tag, null, "test"); + } + // Union of all intrinsics and components of `any` + function App(props) { + var Comp = props.component; + return (react_1["default"].createElement(Comp, null)); + } + // custom components with non-subset props + function render2() { + var C = null; + var a = react_1["default"].createElement(C, { p: true }); + } +} diff --git a/tests/baselines/reference/callsOnComplexSignatures.symbols b/tests/baselines/reference/callsOnComplexSignatures.symbols new file mode 100644 index 0000000000000..dfbddce84ecf7 --- /dev/null +++ b/tests/baselines/reference/callsOnComplexSignatures.symbols @@ -0,0 +1,334 @@ +=== tests/cases/compiler/callsOnComplexSignatures.tsx === +/// +import React from "react"; +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) + +// Simple calls from real usecases +function test1() { +>test1 : Symbol(test1, Decl(callsOnComplexSignatures.tsx, 1, 26)) + + type stringType1 = "foo" | "bar"; +>stringType1 : Symbol(stringType1, Decl(callsOnComplexSignatures.tsx, 4, 18)) + + type stringType2 = "baz" | "bar"; +>stringType2 : Symbol(stringType2, Decl(callsOnComplexSignatures.tsx, 5, 37)) + + interface Temp1 { +>Temp1 : Symbol(Temp1, Decl(callsOnComplexSignatures.tsx, 6, 37)) + + getValue(name: stringType1): number; +>getValue : Symbol(Temp1.getValue, Decl(callsOnComplexSignatures.tsx, 8, 21)) +>name : Symbol(name, Decl(callsOnComplexSignatures.tsx, 9, 17)) +>stringType1 : Symbol(stringType1, Decl(callsOnComplexSignatures.tsx, 4, 18)) + } + + interface Temp2 { +>Temp2 : Symbol(Temp2, Decl(callsOnComplexSignatures.tsx, 10, 5)) + + getValue(name: stringType2): string; +>getValue : Symbol(Temp2.getValue, Decl(callsOnComplexSignatures.tsx, 12, 21)) +>name : Symbol(name, Decl(callsOnComplexSignatures.tsx, 13, 17)) +>stringType2 : Symbol(stringType2, Decl(callsOnComplexSignatures.tsx, 5, 37)) + } + + function test(t: Temp1 | Temp2) { +>test : Symbol(test, Decl(callsOnComplexSignatures.tsx, 14, 5)) +>t : Symbol(t, Decl(callsOnComplexSignatures.tsx, 16, 18)) +>Temp1 : Symbol(Temp1, Decl(callsOnComplexSignatures.tsx, 6, 37)) +>Temp2 : Symbol(Temp2, Decl(callsOnComplexSignatures.tsx, 10, 5)) + + const z = t.getValue("bar"); // Should be fine +>z : Symbol(z, Decl(callsOnComplexSignatures.tsx, 17, 13)) +>t.getValue : Symbol(getValue, Decl(callsOnComplexSignatures.tsx, 8, 21), Decl(callsOnComplexSignatures.tsx, 12, 21)) +>t : Symbol(t, Decl(callsOnComplexSignatures.tsx, 16, 18)) +>getValue : Symbol(getValue, Decl(callsOnComplexSignatures.tsx, 8, 21), Decl(callsOnComplexSignatures.tsx, 12, 21)) + } +} + +function test2() { +>test2 : Symbol(test2, Decl(callsOnComplexSignatures.tsx, 19, 1)) + + interface Messages { +>Messages : Symbol(Messages, Decl(callsOnComplexSignatures.tsx, 21, 18)) + + readonly foo: (options: { [key: string]: any, b: number }) => string; +>foo : Symbol(Messages.foo, Decl(callsOnComplexSignatures.tsx, 22, 24)) +>options : Symbol(options, Decl(callsOnComplexSignatures.tsx, 23, 23)) +>key : Symbol(key, Decl(callsOnComplexSignatures.tsx, 23, 35)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 23, 53)) + + readonly bar: (options: { [key: string]: any, a: string }) => string; +>bar : Symbol(Messages.bar, Decl(callsOnComplexSignatures.tsx, 23, 77)) +>options : Symbol(options, Decl(callsOnComplexSignatures.tsx, 24, 23)) +>key : Symbol(key, Decl(callsOnComplexSignatures.tsx, 24, 35)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 24, 53)) + } + + const messages: Messages = { +>messages : Symbol(messages, Decl(callsOnComplexSignatures.tsx, 27, 9)) +>Messages : Symbol(Messages, Decl(callsOnComplexSignatures.tsx, 21, 18)) + + foo: (options) => "Foo", +>foo : Symbol(foo, Decl(callsOnComplexSignatures.tsx, 27, 32)) +>options : Symbol(options, Decl(callsOnComplexSignatures.tsx, 28, 14)) + + bar: (options) => "Bar", +>bar : Symbol(bar, Decl(callsOnComplexSignatures.tsx, 28, 32)) +>options : Symbol(options, Decl(callsOnComplexSignatures.tsx, 29, 14)) + + }; + + const test1 = (type: "foo" | "bar") => +>test1 : Symbol(test1, Decl(callsOnComplexSignatures.tsx, 32, 9)) +>type : Symbol(type, Decl(callsOnComplexSignatures.tsx, 32, 19)) + + messages[type]({ a: "A", b: 0 }); +>messages : Symbol(messages, Decl(callsOnComplexSignatures.tsx, 27, 9)) +>type : Symbol(type, Decl(callsOnComplexSignatures.tsx, 32, 19)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 33, 24)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 33, 32)) +} + +function test3(items: string[] | number[]) { +>test3 : Symbol(test3, Decl(callsOnComplexSignatures.tsx, 34, 1)) +>items : Symbol(items, Decl(callsOnComplexSignatures.tsx, 36, 15)) + + items.forEach(item => console.log(item)); +>items.forEach : Symbol(forEach, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>items : Symbol(items, Decl(callsOnComplexSignatures.tsx, 36, 15)) +>forEach : Symbol(forEach, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(callsOnComplexSignatures.tsx, 37, 18)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>item : Symbol(item, Decl(callsOnComplexSignatures.tsx, 37, 18)) +} + +function test4( +>test4 : Symbol(test4, Decl(callsOnComplexSignatures.tsx, 38, 1)) + + arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number), +>arg1 : Symbol(arg1, Decl(callsOnComplexSignatures.tsx, 40, 15)) +>objs : Symbol(objs, Decl(callsOnComplexSignatures.tsx, 41, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 41, 22)) +>objs : Symbol(objs, Decl(callsOnComplexSignatures.tsx, 41, 51)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 41, 61)) + + arg2: ((a: {x: number}, b: object) => number) | ((a: object, b: {x: number}) => number), +>arg2 : Symbol(arg2, Decl(callsOnComplexSignatures.tsx, 41, 86)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 42, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 42, 16)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 42, 27)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 42, 54)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 42, 64)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 42, 69)) + + arg3: ((a: {x: number}, ...objs: {y: number}[]) => number) | ((...objs: {x: number}[]) => number), +>arg3 : Symbol(arg3, Decl(callsOnComplexSignatures.tsx, 42, 92)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 43, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 43, 16)) +>objs : Symbol(objs, Decl(callsOnComplexSignatures.tsx, 43, 27)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 43, 38)) +>objs : Symbol(objs, Decl(callsOnComplexSignatures.tsx, 43, 67)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 43, 77)) + + arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number), +>arg4 : Symbol(arg4, Decl(callsOnComplexSignatures.tsx, 43, 102)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 44, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 44, 17)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 44, 28)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 44, 34)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 44, 61)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 44, 66)) + + arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number), +>arg5 : Symbol(arg5, Decl(callsOnComplexSignatures.tsx, 44, 89)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 45, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 45, 17)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 45, 28)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 45, 36)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 45, 65)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 45, 70)) + + arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number), +>arg6 : Symbol(arg6, Decl(callsOnComplexSignatures.tsx, 45, 93)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 46, 12)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 46, 17)) +>b : Symbol(b, Decl(callsOnComplexSignatures.tsx, 46, 28)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 46, 34)) +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 46, 61)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 46, 68)) + +) { + arg1(); +>arg1 : Symbol(arg1, Decl(callsOnComplexSignatures.tsx, 40, 15)) + + arg1({x: 0, y: 0}); +>arg1 : Symbol(arg1, Decl(callsOnComplexSignatures.tsx, 40, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 49, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 49, 15)) + + arg1({x: 0, y: 0}, {x: 1, y: 1}); +>arg1 : Symbol(arg1, Decl(callsOnComplexSignatures.tsx, 40, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 50, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 50, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 50, 24)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 50, 29)) + + arg2({x: 0}, {x: 0}); +>arg2 : Symbol(arg2, Decl(callsOnComplexSignatures.tsx, 41, 86)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 52, 10)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 52, 18)) + + arg3({x: 0}); +>arg3 : Symbol(arg3, Decl(callsOnComplexSignatures.tsx, 42, 92)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 54, 10)) + + arg3({x: 0}, {x: 0, y: 0}); +>arg3 : Symbol(arg3, Decl(callsOnComplexSignatures.tsx, 42, 92)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 55, 10)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 55, 18)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 55, 23)) + + arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}); +>arg3 : Symbol(arg3, Decl(callsOnComplexSignatures.tsx, 42, 92)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 56, 10)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 56, 18)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 56, 23)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 56, 32)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 56, 37)) + + arg4(); +>arg4 : Symbol(arg4, Decl(callsOnComplexSignatures.tsx, 43, 102)) + + arg4({x: 0, y: 0}); +>arg4 : Symbol(arg4, Decl(callsOnComplexSignatures.tsx, 43, 102)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 59, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 59, 15)) + + arg4({x: 0, y: 0}, {x: 0}); +>arg4 : Symbol(arg4, Decl(callsOnComplexSignatures.tsx, 43, 102)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 60, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 60, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 60, 24)) + + arg5(); +>arg5 : Symbol(arg5, Decl(callsOnComplexSignatures.tsx, 44, 89)) + + arg5({x: 0, y: 0}); +>arg5 : Symbol(arg5, Decl(callsOnComplexSignatures.tsx, 44, 89)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 63, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 63, 15)) + + arg5({x: 0, y: 0}, {x: 0}); +>arg5 : Symbol(arg5, Decl(callsOnComplexSignatures.tsx, 44, 89)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 64, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 64, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 64, 24)) + + arg6(); +>arg6 : Symbol(arg6, Decl(callsOnComplexSignatures.tsx, 45, 93)) + + arg6({x: 0, y: 0}); +>arg6 : Symbol(arg6, Decl(callsOnComplexSignatures.tsx, 45, 93)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 67, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 67, 15)) + + arg6({x: 0, y: 0}, {x: 0, y: 0}); +>arg6 : Symbol(arg6, Decl(callsOnComplexSignatures.tsx, 45, 93)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 68, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 68, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 68, 24)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 68, 29)) + + arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}); +>arg6 : Symbol(arg6, Decl(callsOnComplexSignatures.tsx, 45, 93)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 69, 10)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 69, 15)) +>x : Symbol(x, Decl(callsOnComplexSignatures.tsx, 69, 24)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 69, 29)) +>y : Symbol(y, Decl(callsOnComplexSignatures.tsx, 69, 38)) +} + +// JSX Tag names +function test5() { +>test5 : Symbol(test5, Decl(callsOnComplexSignatures.tsx, 70, 1)) + + // Pair of non-like intrinsics + function render(url?: string): React.ReactNode { +>render : Symbol(render, Decl(callsOnComplexSignatures.tsx, 73, 18)) +>url : Symbol(url, Decl(callsOnComplexSignatures.tsx, 75, 20)) +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) +>ReactNode : Symbol(React.ReactNode, Decl(react16.d.ts, 216, 49)) + + const Tag = url ? 'a' : 'button'; +>Tag : Symbol(Tag, Decl(callsOnComplexSignatures.tsx, 76, 13)) +>url : Symbol(url, Decl(callsOnComplexSignatures.tsx, 75, 20)) + + return test; +>Tag : Symbol(Tag, Decl(callsOnComplexSignatures.tsx, 76, 13)) +>Tag : Symbol(Tag, Decl(callsOnComplexSignatures.tsx, 76, 13)) + } + + // Union of all intrinsics and components of `any` + function App(props: { component:React.ReactType }) { +>App : Symbol(App, Decl(callsOnComplexSignatures.tsx, 78, 5)) +>props : Symbol(props, Decl(callsOnComplexSignatures.tsx, 81, 17)) +>component : Symbol(component, Decl(callsOnComplexSignatures.tsx, 81, 25)) +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) +>ReactType : Symbol(React.ReactType, Decl(react16.d.ts, 112, 21)) + + const Comp: React.ReactType = props.component; +>Comp : Symbol(Comp, Decl(callsOnComplexSignatures.tsx, 82, 13)) +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) +>ReactType : Symbol(React.ReactType, Decl(react16.d.ts, 112, 21)) +>props.component : Symbol(component, Decl(callsOnComplexSignatures.tsx, 81, 25)) +>props : Symbol(props, Decl(callsOnComplexSignatures.tsx, 81, 17)) +>component : Symbol(component, Decl(callsOnComplexSignatures.tsx, 81, 25)) + + return (); +>Comp : Symbol(Comp, Decl(callsOnComplexSignatures.tsx, 82, 13)) + } + + // custom components with non-subset props + function render2() { +>render2 : Symbol(render2, Decl(callsOnComplexSignatures.tsx, 84, 5)) + + interface P1 { +>P1 : Symbol(P1, Decl(callsOnComplexSignatures.tsx, 87, 24)) + + p?: boolean; +>p : Symbol(P1.p, Decl(callsOnComplexSignatures.tsx, 88, 22)) + + c?: string; +>c : Symbol(P1.c, Decl(callsOnComplexSignatures.tsx, 89, 24)) + } + interface P2 { +>P2 : Symbol(P2, Decl(callsOnComplexSignatures.tsx, 91, 9)) + + p?: boolean; +>p : Symbol(P2.p, Decl(callsOnComplexSignatures.tsx, 92, 22)) + + c?: any; +>c : Symbol(P2.c, Decl(callsOnComplexSignatures.tsx, 93, 24)) + + d?: any; +>d : Symbol(P2.d, Decl(callsOnComplexSignatures.tsx, 94, 20)) + } + + var C: React.ComponentType | React.ComponentType = null as any; +>C : Symbol(C, Decl(callsOnComplexSignatures.tsx, 98, 11)) +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) +>ComponentType : Symbol(React.ComponentType, Decl(react16.d.ts, 117, 60)) +>P1 : Symbol(P1, Decl(callsOnComplexSignatures.tsx, 87, 24)) +>React : Symbol(React, Decl(callsOnComplexSignatures.tsx, 1, 6)) +>ComponentType : Symbol(React.ComponentType, Decl(react16.d.ts, 117, 60)) +>P2 : Symbol(P2, Decl(callsOnComplexSignatures.tsx, 91, 9)) + + const a = ; +>a : Symbol(a, Decl(callsOnComplexSignatures.tsx, 100, 13)) +>C : Symbol(C, Decl(callsOnComplexSignatures.tsx, 98, 11)) +>p : Symbol(p, Decl(callsOnComplexSignatures.tsx, 100, 20)) + } +} + diff --git a/tests/baselines/reference/callsOnComplexSignatures.types b/tests/baselines/reference/callsOnComplexSignatures.types new file mode 100644 index 0000000000000..4eb90ac43e345 --- /dev/null +++ b/tests/baselines/reference/callsOnComplexSignatures.types @@ -0,0 +1,416 @@ +=== tests/cases/compiler/callsOnComplexSignatures.tsx === +/// +import React from "react"; +>React : typeof React + +// Simple calls from real usecases +function test1() { +>test1 : () => void + + type stringType1 = "foo" | "bar"; +>stringType1 : "foo" | "bar" + + type stringType2 = "baz" | "bar"; +>stringType2 : "bar" | "baz" + + interface Temp1 { + getValue(name: stringType1): number; +>getValue : (name: "foo" | "bar") => number +>name : "foo" | "bar" + } + + interface Temp2 { + getValue(name: stringType2): string; +>getValue : (name: "bar" | "baz") => string +>name : "bar" | "baz" + } + + function test(t: Temp1 | Temp2) { +>test : (t: Temp1 | Temp2) => void +>t : Temp1 | Temp2 + + const z = t.getValue("bar"); // Should be fine +>z : React.ReactText +>t.getValue("bar") : React.ReactText +>t.getValue : ((name: "foo" | "bar") => number) | ((name: "bar" | "baz") => string) +>t : Temp1 | Temp2 +>getValue : ((name: "foo" | "bar") => number) | ((name: "bar" | "baz") => string) +>"bar" : "bar" + } +} + +function test2() { +>test2 : () => void + + interface Messages { + readonly foo: (options: { [key: string]: any, b: number }) => string; +>foo : (options: { [key: string]: any; b: number; }) => string +>options : { [key: string]: any; b: number; } +>key : string +>b : number + + readonly bar: (options: { [key: string]: any, a: string }) => string; +>bar : (options: { [key: string]: any; a: string; }) => string +>options : { [key: string]: any; a: string; } +>key : string +>a : string + } + + const messages: Messages = { +>messages : Messages +>{ foo: (options) => "Foo", bar: (options) => "Bar", } : { foo: (options: { [key: string]: any; b: number; }) => string; bar: (options: { [key: string]: any; a: string; }) => string; } + + foo: (options) => "Foo", +>foo : (options: { [key: string]: any; b: number; }) => string +>(options) => "Foo" : (options: { [key: string]: any; b: number; }) => string +>options : { [key: string]: any; b: number; } +>"Foo" : "Foo" + + bar: (options) => "Bar", +>bar : (options: { [key: string]: any; a: string; }) => string +>(options) => "Bar" : (options: { [key: string]: any; a: string; }) => string +>options : { [key: string]: any; a: string; } +>"Bar" : "Bar" + + }; + + const test1 = (type: "foo" | "bar") => +>test1 : (type: "foo" | "bar") => string +>(type: "foo" | "bar") => messages[type]({ a: "A", b: 0 }) : (type: "foo" | "bar") => string +>type : "foo" | "bar" + + messages[type]({ a: "A", b: 0 }); +>messages[type]({ a: "A", b: 0 }) : string +>messages[type] : ((options: { [key: string]: any; b: number; }) => string) | ((options: { [key: string]: any; a: string; }) => string) +>messages : Messages +>type : "foo" | "bar" +>{ a: "A", b: 0 } : { a: string; b: number; } +>a : string +>"A" : "A" +>b : number +>0 : 0 +} + +function test3(items: string[] | number[]) { +>test3 : (items: string[] | number[]) => void +>items : string[] | number[] + + items.forEach(item => console.log(item)); +>items.forEach(item => console.log(item)) : void +>items.forEach : ((callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void) | ((callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void) +>items : string[] | number[] +>forEach : ((callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void) | ((callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void) +>item => console.log(item) : (item: any) => void +>item : any +>console.log(item) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>item : any +} + +function test4( +>test4 : (arg1: ((...objs: { x: number; }[]) => number) | ((...objs: { y: number; }[]) => number), arg2: ((a: { x: number; }, b: object) => number) | ((a: object, b: { x: number; }) => number), arg3: ((a: { x: number; }, ...objs: { y: number; }[]) => number) | ((...objs: { x: number; }[]) => number), arg4: ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number), arg5: ((a?: { x: number; } | undefined, ...b: { x: number; }[]) => number) | ((a?: { y: number; } | undefined) => number), arg6: ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number)) => void + + arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number), +>arg1 : ((...objs: { x: number; }[]) => number) | ((...objs: { y: number; }[]) => number) +>objs : { x: number; }[] +>x : number +>objs : { y: number; }[] +>y : number + + arg2: ((a: {x: number}, b: object) => number) | ((a: object, b: {x: number}) => number), +>arg2 : ((a: { x: number; }, b: object) => number) | ((a: object, b: { x: number; }) => number) +>a : { x: number; } +>x : number +>b : object +>a : object +>b : { x: number; } +>x : number + + arg3: ((a: {x: number}, ...objs: {y: number}[]) => number) | ((...objs: {x: number}[]) => number), +>arg3 : ((a: { x: number; }, ...objs: { y: number; }[]) => number) | ((...objs: { x: number; }[]) => number) +>a : { x: number; } +>x : number +>objs : { y: number; }[] +>y : number +>objs : { x: number; }[] +>x : number + + arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number), +>arg4 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number) +>a : { x: number; } | undefined +>x : number +>b : { x: number; } | undefined +>x : number +>a : { y: number; } | undefined +>y : number + + arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number), +>arg5 : ((a?: { x: number; } | undefined, ...b: { x: number; }[]) => number) | ((a?: { y: number; } | undefined) => number) +>a : { x: number; } | undefined +>x : number +>b : { x: number; }[] +>x : number +>a : { y: number; } | undefined +>y : number + + arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number), +>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number) +>a : { x: number; } | undefined +>x : number +>b : { x: number; } | undefined +>x : number +>a : { y: number; }[] +>y : number + +) { + arg1(); +>arg1() : number +>arg1 : ((...objs: { x: number; }[]) => number) | ((...objs: { y: number; }[]) => number) + + arg1({x: 0, y: 0}); +>arg1({x: 0, y: 0}) : number +>arg1 : ((...objs: { x: number; }[]) => number) | ((...objs: { y: number; }[]) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg1({x: 0, y: 0}, {x: 1, y: 1}); +>arg1({x: 0, y: 0}, {x: 1, y: 1}) : number +>arg1 : ((...objs: { x: number; }[]) => number) | ((...objs: { y: number; }[]) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 1, y: 1} : { x: number; y: number; } +>x : number +>1 : 1 +>y : number +>1 : 1 + + arg2({x: 0}, {x: 0}); +>arg2({x: 0}, {x: 0}) : number +>arg2 : ((a: { x: number; }, b: object) => number) | ((a: object, b: { x: number; }) => number) +>{x: 0} : { x: number; } +>x : number +>0 : 0 +>{x: 0} : { x: number; } +>x : number +>0 : 0 + + arg3({x: 0}); +>arg3({x: 0}) : number +>arg3 : ((a: { x: number; }, ...objs: { y: number; }[]) => number) | ((...objs: { x: number; }[]) => number) +>{x: 0} : { x: number; } +>x : number +>0 : 0 + + arg3({x: 0}, {x: 0, y: 0}); +>arg3({x: 0}, {x: 0, y: 0}) : number +>arg3 : ((a: { x: number; }, ...objs: { y: number; }[]) => number) | ((...objs: { x: number; }[]) => number) +>{x: 0} : { x: number; } +>x : number +>0 : 0 +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}); +>arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}) : number +>arg3 : ((a: { x: number; }, ...objs: { y: number; }[]) => number) | ((...objs: { x: number; }[]) => number) +>{x: 0} : { x: number; } +>x : number +>0 : 0 +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg4(); +>arg4() : number +>arg4 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number) + + arg4({x: 0, y: 0}); +>arg4({x: 0, y: 0}) : number +>arg4 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg4({x: 0, y: 0}, {x: 0}); +>arg4({x: 0, y: 0}, {x: 0}) : number +>arg4 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 0} : { x: number; } +>x : number +>0 : 0 + + arg5(); +>arg5() : number +>arg5 : ((a?: { x: number; } | undefined, ...b: { x: number; }[]) => number) | ((a?: { y: number; } | undefined) => number) + + arg5({x: 0, y: 0}); +>arg5({x: 0, y: 0}) : number +>arg5 : ((a?: { x: number; } | undefined, ...b: { x: number; }[]) => number) | ((a?: { y: number; } | undefined) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg5({x: 0, y: 0}, {x: 0}); +>arg5({x: 0, y: 0}, {x: 0}) : number +>arg5 : ((a?: { x: number; } | undefined, ...b: { x: number; }[]) => number) | ((a?: { y: number; } | undefined) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 0} : { x: number; } +>x : number +>0 : 0 + + arg6(); +>arg6() : number +>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number) + + arg6({x: 0, y: 0}); +>arg6({x: 0, y: 0}) : number +>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg6({x: 0, y: 0}, {x: 0, y: 0}); +>arg6({x: 0, y: 0}, {x: 0, y: 0}) : number +>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}); +>arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}) : number +>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number; }[]) => number) +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{x: 0, y: 0} : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 +>{y: 0} : { y: number; } +>y : number +>0 : 0 +} + +// JSX Tag names +function test5() { +>test5 : () => void + + // Pair of non-like intrinsics + function render(url?: string): React.ReactNode { +>render : (url?: string | undefined) => React.ReactNode +>url : string | undefined +>React : any + + const Tag = url ? 'a' : 'button'; +>Tag : "a" | "button" +>url ? 'a' : 'button' : "a" | "button" +>url : string | undefined +>'a' : "a" +>'button' : "button" + + return test; +>test : JSX.Element +>Tag : "a" | "button" +>Tag : "a" | "button" + } + + // Union of all intrinsics and components of `any` + function App(props: { component:React.ReactType }) { +>App : (props: { component: React.ReactType; }) => JSX.Element +>props : { component: React.ReactType; } +>component : React.ReactType +>React : any + + const Comp: React.ReactType = props.component; +>Comp : React.ReactType +>React : any +>props.component : React.ReactType +>props : { component: React.ReactType; } +>component : React.ReactType + + return (); +>() : JSX.Element +> : JSX.Element +>Comp : React.ReactType + } + + // custom components with non-subset props + function render2() { +>render2 : () => void + + interface P1 { + p?: boolean; +>p : boolean | undefined + + c?: string; +>c : string | undefined + } + interface P2 { + p?: boolean; +>p : boolean | undefined + + c?: any; +>c : any + + d?: any; +>d : any + } + + var C: React.ComponentType | React.ComponentType = null as any; +>C : React.ComponentClass | React.StatelessComponent | React.ComponentClass | React.StatelessComponent +>React : any +>React : any +>null as any : any +>null : null + + const a = ; +>a : JSX.Element +> : JSX.Element +>C : React.ComponentClass | React.StatelessComponent | React.ComponentClass | React.StatelessComponent +>p : true +>true : true + } +} + diff --git a/tests/baselines/reference/controlFlowArrayErrors.errors.txt b/tests/baselines/reference/controlFlowArrayErrors.errors.txt index 403cafacf5d23..59ec0b44f5c93 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.errors.txt +++ b/tests/baselines/reference/controlFlowArrayErrors.errors.txt @@ -6,7 +6,7 @@ tests/cases/compiler/controlFlowArrayErrors.ts(19,9): error TS7034: Variable 'x' tests/cases/compiler/controlFlowArrayErrors.ts(22,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. tests/cases/compiler/controlFlowArrayErrors.ts(29,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. tests/cases/compiler/controlFlowArrayErrors.ts(34,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. -tests/cases/compiler/controlFlowArrayErrors.ts(48,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((...items: (string | number)[]) => number) | ((...items: boolean[]) => number)' has no compatible call signatures. +tests/cases/compiler/controlFlowArrayErrors.ts(48,12): error TS2345: Argument of type '99' is not assignable to parameter of type 'never'. tests/cases/compiler/controlFlowArrayErrors.ts(56,12): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. tests/cases/compiler/controlFlowArrayErrors.ts(60,11): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. tests/cases/compiler/controlFlowArrayErrors.ts(63,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. @@ -77,8 +77,8 @@ tests/cases/compiler/controlFlowArrayErrors.ts(63,9): error TS7005: Variable 'x' } x; // boolean[] | (string | number)[] x.push(99); // Error - ~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((...items: (string | number)[]) => number) | ((...items: boolean[]) => number)' has no compatible call signatures. + ~~ +!!! error TS2345: Argument of type '99' is not assignable to parameter of type 'never'. } function f7() { diff --git a/tests/baselines/reference/functionCallOnConstrainedTypeVariable.errors.txt b/tests/baselines/reference/functionCallOnConstrainedTypeVariable.errors.txt index 1ff56c7612f7b..f7ea353e10f3c 100644 --- a/tests/baselines/reference/functionCallOnConstrainedTypeVariable.errors.txt +++ b/tests/baselines/reference/functionCallOnConstrainedTypeVariable.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(11,3): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. -tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(15,3): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. -tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(18,3): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. -tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(19,3): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. +tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(11,7): error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'. +tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(15,7): error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'. +tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(18,5): error TS2345: Argument of type '""' is not assignable to parameter of type 'never'. +tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(19,3): error TS2554: Expected 1 arguments, but got 4. ==== tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts (4 errors) ==== @@ -16,20 +16,20 @@ tests/cases/compiler/functionCallOnConstrainedTypeVariable.ts(19,3): error TS234 function call0(p: A | B) { p.a("s"); // Error - ~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. + ~~~ +!!! error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'. } function callN(p: T) { p.a("s"); // Error - ~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. + ~~~ +!!! error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'. var a: T["a"] = p.a; a(""); // Error - ~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. + ~~ +!!! error TS2345: Argument of type '""' is not assignable to parameter of type 'never'. a("", "", "", ""); // Error ~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((x: number) => string) | ((x: boolean) => string)' has no compatible call signatures. +!!! error TS2554: Expected 1 arguments, but got 4. } \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType1.errors.txt b/tests/baselines/reference/tsxUnionElementType1.errors.txt index 9290e734d8388..e2f5bef633392 100644 --- a/tests/baselines/reference/tsxUnionElementType1.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(12,2): error TS2604: JSX element type 'SFCComp' does not have any construct or call signatures. +tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type 'true' is not assignable to type 'never'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -14,5 +14,6 @@ tests/cases/conformance/jsx/file.tsx(12,2): error TS2604: JSX element type 'SFCC var SFCComp = SFC1 || SFC2; - ~~~~~~~ -!!! error TS2604: JSX element type 'SFCComp' does not have any construct or call signatures. \ No newline at end of file + ~ +!!! error TS2322: Type 'true' is not assignable to type 'never'. +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:23: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & { x: number; } & { x: boolean; }' \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType2.errors.txt b/tests/baselines/reference/tsxUnionElementType2.errors.txt index 091d828dfe373..87f1d7fc2dc58 100644 --- a/tests/baselines/reference/tsxUnionElementType2.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(12,2): error TS2604: JSX element type 'SFCComp' does not have any construct or call signatures. +tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type 'string' is not assignable to type 'never'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -14,5 +14,6 @@ tests/cases/conformance/jsx/file.tsx(12,2): error TS2604: JSX element type 'SFCC var SFCComp = SFC1 || SFC2; - ~~~~~~~ -!!! error TS2604: JSX element type 'SFCComp' does not have any construct or call signatures. \ No newline at end of file + ~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:23: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & { x: number; } & { x: boolean; }' \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType3.errors.txt b/tests/baselines/reference/tsxUnionElementType3.errors.txt index bfdb61f406107..8f8ce3c28bd73 100644 --- a/tests/baselines/reference/tsxUnionElementType3.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType3.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(32,10): error TS2604: JSX element type 'RCComp' does not have any construct or call signatures. +tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not assignable to type 'number & string'. + Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -34,8 +35,10 @@ tests/cases/conformance/jsx/file.tsx(32,10): error TS2604: JSX element type 'RCC var RCComp = RC1 || RC2; // OK let a = ; - ~~~~~~ -!!! error TS2604: JSX element type 'RCComp' does not have any construct or call signatures. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number & string'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let a1 = ; let a2 = ; let b = diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 4ca07f265414f..4b059d093f8ff 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(32,10): error TS2604: JSX element type 'RCComp' does not have any construct or call signatures. +tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'number & string'. + Type 'true' is not assignable to type 'number'. tests/cases/conformance/jsx/file.tsx(33,10): error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. @@ -38,8 +39,10 @@ tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; } var PartRCComp = RC1 || RC4; // Error let a = ; - ~~~~~~ -!!! error TS2604: JSX element type 'RCComp' does not have any construct or call signatures. + ~ +!!! error TS2322: Type 'true' is not assignable to type 'number & string'. +!!! error TS2322: Type 'true' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let b = ~~~~~~~~~~ !!! error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. diff --git a/tests/baselines/reference/unionTypeCallSignatures.errors.txt b/tests/baselines/reference/unionTypeCallSignatures.errors.txt index 5a67bde722c0e..c260d7ce51143 100644 --- a/tests/baselines/reference/unionTypeCallSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeCallSignatures.errors.txt @@ -2,9 +2,11 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(9,43): error TS23 tests/cases/conformance/types/union/unionTypeCallSignatures.ts(10,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(15,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,32): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. + Type '10' is not assignable to type 'string'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,32): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. + Type '"hello"' is not assignable to type 'number'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(29,1): error TS2554: Expected 2 arguments, but got 0. @@ -56,14 +58,17 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(73,12): error TS2 var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; }; unionOfDifferentParameterTypes(10);// error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. +!!! error TS2345: Type '10' is not assignable to type 'string'. unionOfDifferentParameterTypes("hello");// error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. + ~~~~~~~ +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. +!!! error TS2345: Type '"hello"' is not assignable to type 'number'. unionOfDifferentParameterTypes();// error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: number) => number) | ((a: string) => Date)' has no compatible call signatures. +!!! error TS2554: Expected 1 arguments, but got 0. +!!! related TS6210 tests/cases/conformance/types/union/unionTypeCallSignatures.ts:18:40: An argument for 'a' was not provided. var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; }; unionOfDifferentNumberOfSignatures(); // error - no call signatures diff --git a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt index a5ad21ba5804d..92adc83a0d286 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt @@ -2,9 +2,11 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(9,47): error tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(10,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(15,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,36): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. + Type '10' is not assignable to type 'string'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. + Type '"hello"' is not assignable to type 'number'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,40): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(29,1): error TS2554: Expected 2 arguments, but got 0. @@ -55,14 +57,17 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): erro var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; }; new unionOfDifferentParameterTypes(10);// error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'. +!!! error TS2345: Type '10' is not assignable to type 'string'. new unionOfDifferentParameterTypes("hello");// error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + ~~~~~~~ +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'. +!!! error TS2345: Type '"hello"' is not assignable to type 'number'. new unionOfDifferentParameterTypes();// error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +!!! error TS2554: Expected 1 arguments, but got 0. +!!! related TS6210 tests/cases/conformance/types/union/unionTypeConstructSignatures.ts:18:44: An argument for 'a' was not provided. var unionOfDifferentNumberOfSignatures: { new (a: number): number; } | { new (a: number): Date; new (a: string): boolean; }; new unionOfDifferentNumberOfSignatures(); // error - no call signatures diff --git a/tests/baselines/reference/unionTypeMembers.errors.txt b/tests/baselines/reference/unionTypeMembers.errors.txt index 6d9f1321a74ca..2a2f93d1a071c 100644 --- a/tests/baselines/reference/unionTypeMembers.errors.txt +++ b/tests/baselines/reference/unionTypeMembers.errors.txt @@ -1,4 +1,6 @@ -tests/cases/conformance/types/union/unionTypeMembers.ts(44,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: string) => string) | ((a: number) => number)' has no compatible call signatures. +tests/cases/conformance/types/union/unionTypeMembers.ts(44,38): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'. + Type 'string' is not assignable to type 'string & number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/union/unionTypeMembers.ts(51,3): error TS2339: Property 'propertyOnlyInI1' does not exist on type 'I1 | I2'. Property 'propertyOnlyInI1' does not exist on type 'I2'. tests/cases/conformance/types/union/unionTypeMembers.ts(52,3): error TS2339: Property 'propertyOnlyInI2' does not exist on type 'I1 | I2'. @@ -54,8 +56,10 @@ tests/cases/conformance/types/union/unionTypeMembers.ts(54,3): error TS2339: Pro strOrNum = x.commonMethodDifferentReturnType(str); // string | union x.commonMethodDifferentParameterType; // No error - property exists x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((a: string) => string) | ((a: number) => number)' has no compatible call signatures. + ~~~~~~~~ +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'. +!!! error TS2345: Type 'string' is not assignable to type 'string & number'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. // and the call signatures arent identical num = x.commonMethodWithTypeParameter(num); num = x.commonMethodWithOwnTypeParameter(num); diff --git a/tests/cases/compiler/callsOnComplexSignatures.tsx b/tests/cases/compiler/callsOnComplexSignatures.tsx new file mode 100644 index 0000000000000..eb1ff9e753a6e --- /dev/null +++ b/tests/cases/compiler/callsOnComplexSignatures.tsx @@ -0,0 +1,106 @@ +// @jsx: react +// @esModuleInterop: true +// @strict: true +/// +import React from "react"; + +// Simple calls from real usecases +function test1() { + type stringType1 = "foo" | "bar"; + type stringType2 = "baz" | "bar"; + + interface Temp1 { + getValue(name: stringType1): number; + } + + interface Temp2 { + getValue(name: stringType2): string; + } + + function test(t: Temp1 | Temp2) { + const z = t.getValue("bar"); // Should be fine + } +} + +function test2() { + interface Messages { + readonly foo: (options: { [key: string]: any, b: number }) => string; + readonly bar: (options: { [key: string]: any, a: string }) => string; + } + + const messages: Messages = { + foo: (options) => "Foo", + bar: (options) => "Bar", + }; + + const test1 = (type: "foo" | "bar") => + messages[type]({ a: "A", b: 0 }); +} + +function test3(items: string[] | number[]) { + items.forEach(item => console.log(item)); +} + +function test4( + arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number), + arg2: ((a: {x: number}, b: object) => number) | ((a: object, b: {x: number}) => number), + arg3: ((a: {x: number}, ...objs: {y: number}[]) => number) | ((...objs: {x: number}[]) => number), + arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number), + arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number), + arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number), +) { + arg1(); + arg1({x: 0, y: 0}); + arg1({x: 0, y: 0}, {x: 1, y: 1}); + + arg2({x: 0}, {x: 0}); + + arg3({x: 0}); + arg3({x: 0}, {x: 0, y: 0}); + arg3({x: 0}, {x: 0, y: 0}, {x: 0, y: 0}); + + arg4(); + arg4({x: 0, y: 0}); + arg4({x: 0, y: 0}, {x: 0}); + + arg5(); + arg5({x: 0, y: 0}); + arg5({x: 0, y: 0}, {x: 0}); + + arg6(); + arg6({x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}); + arg6({x: 0, y: 0}, {x: 0, y: 0}, {y: 0}); +} + +// JSX Tag names +function test5() { + // Pair of non-like intrinsics + function render(url?: string): React.ReactNode { + const Tag = url ? 'a' : 'button'; + return test; + } + + // Union of all intrinsics and components of `any` + function App(props: { component:React.ReactType }) { + const Comp: React.ReactType = props.component; + return (); + } + + // custom components with non-subset props + function render2() { + interface P1 { + p?: boolean; + c?: string; + } + interface P2 { + p?: boolean; + c?: any; + d?: any; + } + + var C: React.ComponentType | React.ComponentType = null as any; + + const a = ; + } +} diff --git a/tests/cases/fourslash/calledUnionsOfDissimilarTyeshaveGoodDisplay.ts b/tests/cases/fourslash/calledUnionsOfDissimilarTyeshaveGoodDisplay.ts new file mode 100644 index 0000000000000..e8c42871b6748 --- /dev/null +++ b/tests/cases/fourslash/calledUnionsOfDissimilarTyeshaveGoodDisplay.ts @@ -0,0 +1,53 @@ +/// + +////declare const callableThing1: +//// | ((o1: {x: number}) => void) +//// | ((o1: {y: number}) => void) +//// ; +//// +////callableThing1(/*1*/); +//// +////declare const callableThing2: +//// | ((o1: {x: number}) => void) +//// | ((o2: {y: number}) => void) +//// ; +//// +////callableThing2(/*2*/); +//// +////declare const callableThing3: +//// | ((o1: {x: number}) => void) +//// | ((o2: {y: number}) => void) +//// | ((o3: {z: number}) => void) +//// | ((o4: {u: number}) => void) +//// | ((o5: {v: number}) => void) +//// ; +//// +////callableThing3(/*3*/); +//// +////declare const callableThing4: +//// | ((o1: {x: number}) => void) +//// | ((o2: {y: number}) => void) +//// | ((o3: {z: number}) => void) +//// | ((o4: {u: number}) => void) +//// | ((o5: {v: number}) => void) +//// | ((o6: {w: number}) => void) +//// ; +//// +////callableThing4(/*4*/); + +verify.signatureHelp({ + marker: "1", + text: "callableThing1(o1: { x: number; } & { y: number; }): void" +}, +{ + marker: "2", + text: "callableThing2(arg0: { x: number; } & { y: number; }): void" +}, +{ + marker: "3", + text: "callableThing3(arg0: { x: number; } & { y: number; } & { z: number; } & { u: number; } & { v: number; }): void" +}, +{ + marker: "4", + text: "callableThing4(arg0: { x: number; } & { y: number; } & { z: number; } & { u: number; } & { v: number; } & { w: number; }): void" +}); diff --git a/tests/cases/fourslash/tsxCompletionUnionElementType.ts b/tests/cases/fourslash/tsxCompletionUnionElementType.ts index 7d458f83493af..b554d3851798d 100644 --- a/tests/cases/fourslash/tsxCompletionUnionElementType.ts +++ b/tests/cases/fourslash/tsxCompletionUnionElementType.ts @@ -19,4 +19,4 @@ //// var SFCComp = SFC1 || SFC2; //// -verify.completions({ marker: "", exact: undefined }); +verify.completions({ marker: "", exact: ["x"] }); diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts index 9e4cb4e1b1be9..957b6b811e0d8 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts @@ -22,5 +22,5 @@ //// <[|SFC/*one*/Comp|] x /> verify.goToDefinition({ - "one": ["def"], + "one": ["def", "pt1"], });