From 7ec7f02ec3d65d2b37c8d41bcf966ec98bb4ee2e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 23 Mar 2019 10:46:46 -0700 Subject: [PATCH 1/6] Instantiate contextual type using non-fixing mapper --- src/compiler/checker.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea44fb0f3bd74..456d5b223250d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14470,7 +14470,7 @@ namespace ts { const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); inferTypes([inference], sourceType, templateType); - return getTypeFromInference(inference); + return getTypeFromInference(inference) || emptyObjectType; } function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean) { @@ -14514,7 +14514,7 @@ namespace ts { function getTypeFromInference(inference: InferenceInfo) { return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : - emptyObjectType; + undefined; } function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) { @@ -15016,8 +15016,8 @@ namespace ts { function getInferredType(context: InferenceContext, index: number): Type { const inference = context.inferences[index]; - let inferredType = inference.inferredType; - if (!inferredType) { + if (!inference.inferredType) { + let inferredType: Type | undefined; const signature = context.signature; if (signature) { const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined; @@ -15048,27 +15048,24 @@ namespace ts { // parameter should be instantiated to the empty object type. inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper)); } - else { - inferredType = getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); - } } } else { inferredType = getTypeFromInference(inference); } - inference.inferredType = inferredType; + inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper); - if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } } - return inferredType; + return inference.inferredType; } function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type { @@ -18046,8 +18043,13 @@ namespace ts { function instantiateContextualType(contextualType: Type | undefined, node: Expression): Type | undefined { if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { const inferenceContext = getInferenceContext(node); - if (inferenceContext && inferenceContext.returnMapper) { - return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); + if (inferenceContext) { + if ((isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)) && isContextSensitive(node)) { + return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper); + } + if (inferenceContext.returnMapper) { + return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); + } } } return contextualType; From 3d0e2f5f454c127b3753aaa400ecbdda98fda66b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 24 Mar 2019 11:15:51 -0700 Subject: [PATCH 2/6] Introduce ContextFlags to propagate origin of request for contextual type --- src/compiler/checker.ts | 70 ++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 456d5b223250d..26727e82c635c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -701,6 +701,11 @@ namespace ts { IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help } + const enum ContextFlags { + None = 0, + Signature = 1 << 0, // Obtaining contextual signature + } + const enum CallbackCheck { None, Bivariant, @@ -17751,7 +17756,7 @@ namespace ts { return undefined; } - function getContextualTypeForBinaryOperand(node: Expression): Type | undefined { + function getContextualTypeForBinaryOperand(node: Expression, contextFlags?: ContextFlags): Type | undefined { const binaryExpression = node.parent; const { left, operatorToken, right } = binaryExpression; switch (operatorToken.kind) { @@ -17768,12 +17773,12 @@ namespace ts { // When an || expression has a contextual type, the operands are contextually typed by that type. When an || // expression has no contextual type, the right operand is contextually typed by the type of the left operand, // except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}` - const type = getContextualType(binaryExpression); + const type = getContextualType(binaryExpression, contextFlags); return !type && node === right && !isDefaultedExpandoInitializer(binaryExpression) ? getTypeOfExpression(left) : type; case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: - return node === right ? getContextualType(binaryExpression) : undefined; + return node === right ? getContextualType(binaryExpression, contextFlags) : undefined; default: return undefined; } @@ -17882,19 +17887,18 @@ namespace ts { // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one // exists. Otherwise, it is the type of the string index signature in T, if one exists. - function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration): Type | undefined { + function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration, contextFlags?: ContextFlags): Type | undefined { Debug.assert(isObjectLiteralMethod(node)); if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } - - return getContextualTypeForObjectLiteralElement(node); + return getContextualTypeForObjectLiteralElement(node, contextFlags); } - function getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike) { + function getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike, contextFlags?: ContextFlags) { const objectLiteral = element.parent; - const type = getApparentTypeOfContextualType(objectLiteral); + const type = getApparentTypeOfContextualType(objectLiteral, contextFlags); if (type) { if (!hasNonBindableDynamicName(element)) { // For a (non-symbol) computed property, there is no reason to look up the name @@ -17906,11 +17910,9 @@ namespace ts { return propertyType; } } - return isNumericName(element.name!) && getIndexTypeOfContextualType(type, IndexKind.Number) || getIndexTypeOfContextualType(type, IndexKind.String); } - return undefined; } @@ -17925,9 +17927,9 @@ namespace ts { } // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type. - function getContextualTypeForConditionalOperand(node: Expression): Type | undefined { + function getContextualTypeForConditionalOperand(node: Expression, contextFlags?: ContextFlags): Type | undefined { const conditional = node.parent; - return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; + return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional, contextFlags) : undefined; } function getContextualTypeForChildJsxExpression(node: JsxElement, child: JsxChild) { @@ -18022,8 +18024,8 @@ namespace ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. - function getApparentTypeOfContextualType(node: Expression): Type | undefined { - const contextualType = instantiateContextualType(getContextualType(node), node); + function getApparentTypeOfContextualType(node: Expression, contextFlags?: ContextFlags): Type | undefined { + const contextualType = instantiateContextualType(getContextualType(node, contextFlags), node, contextFlags); if (contextualType) { const apparentType = mapType(contextualType, getApparentType, /*noReductions*/ true); if (apparentType.flags & TypeFlags.Union) { @@ -18040,13 +18042,19 @@ namespace ts { // If the given contextual type contains instantiable types and if a mapper representing // return type inferences is available, instantiate those types using that mapper. - function instantiateContextualType(contextualType: Type | undefined, node: Expression): Type | undefined { + function instantiateContextualType(contextualType: Type | undefined, node: Expression, contextFlags?: ContextFlags): Type | undefined { if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { const inferenceContext = getInferenceContext(node); - if (inferenceContext) { - if ((isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)) && isContextSensitive(node)) { + // If no inferences have been made, nothing is gained from instantiating as type parameters + // would just be replaced with their defaults similar to the apparent type. + if (inferenceContext && some(inferenceContext.inferences, hasInferenceCandidates)) { + // For contextual signatures we incorporate all inferences made so far, e.g. from return + // types as well as arguments to the left in a function call. + if (contextFlags && contextFlags & ContextFlags.Signature) { return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper); } + // For other purposes (e.g. determining whether to produce literal types) we only + // incorporate inferences made from the return type in a function call. if (inferenceContext.returnMapper) { return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); } @@ -18088,7 +18096,7 @@ namespace ts { * @param node the expression whose contextual type will be returned. * @returns the contextual type of an expression. */ - function getContextualType(node: Expression): Type | undefined { + function getContextualType(node: Expression, contextFlags?: ContextFlags): Type | undefined { if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; @@ -18118,26 +18126,26 @@ namespace ts { case SyntaxKind.AsExpression: return isConstTypeReference((parent).type) ? undefined : getTypeFromTypeNode((parent).type); case SyntaxKind.BinaryExpression: - return getContextualTypeForBinaryOperand(node); + return getContextualTypeForBinaryOperand(node, contextFlags); case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - return getContextualTypeForObjectLiteralElement(parent); + return getContextualTypeForObjectLiteralElement(parent, contextFlags); case SyntaxKind.SpreadAssignment: - return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression); + return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression, contextFlags); case SyntaxKind.ArrayLiteralExpression: { const arrayLiteral = parent; - const type = getApparentTypeOfContextualType(arrayLiteral); + const type = getApparentTypeOfContextualType(arrayLiteral, contextFlags); return getContextualTypeForElementExpression(type, indexOfNode(arrayLiteral.elements, node)); } case SyntaxKind.ConditionalExpression: - return getContextualTypeForConditionalOperand(node); + return getContextualTypeForConditionalOperand(node, contextFlags); case SyntaxKind.TemplateSpan: Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression); return getContextualTypeForSubstitutionExpression(parent.parent, node); case SyntaxKind.ParenthesizedExpression: { // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast. const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined; - return tag ? getTypeFromTypeNode(tag.typeExpression!.type) : getContextualType(parent); + return tag ? getTypeFromTypeNode(tag.typeExpression!.type) : getContextualType(parent, contextFlags); } case SyntaxKind.JsxExpression: return getContextualTypeForJsxExpression(parent); @@ -18328,12 +18336,6 @@ namespace ts { : undefined; } - function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) { - return isObjectLiteralMethod(node) ? - getContextualTypeForObjectLiteralMethod(node) : - getApparentTypeOfContextualType(node); - } - // 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 @@ -18345,7 +18347,9 @@ namespace ts { if (typeTagSignature) { return typeTagSignature; } - const type = getContextualTypeForFunctionLikeDeclaration(node); + const type = isObjectLiteralMethod(node) ? + getContextualTypeForObjectLiteralMethod(node, ContextFlags.Signature) : + getApparentTypeOfContextualType(node, ContextFlags.Signature); if (!type) { return undefined; } @@ -20249,7 +20253,7 @@ namespace ts { return type; } - function getSpreadArgumentType(args: ReadonlyArray, index: number, argCount: number, restType: TypeParameter, context: InferenceContext | undefined) { + function getSpreadArgumentType(args: ReadonlyArray, index: number, argCount: number, restType: Type, context: InferenceContext | undefined) { if (index >= argCount - 1) { const arg = args[argCount - 1]; if (isSpreadArgument(arg)) { @@ -20260,7 +20264,7 @@ namespace ts { getArrayifiedType(checkExpressionWithContextualType((arg).expression, restType, context, CheckMode.Normal)); } } - const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType; + const contextualType = getIndexedAccessType(restType, numberType); const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index); const types = []; let spreadIndex = -1; From 6dc8b5f8fbce993c5509704d64c221d652493f06 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 24 Mar 2019 11:24:45 -0700 Subject: [PATCH 3/6] Accept new baselines --- .../reference/fillInMissingTypeArgsOnConstructCalls.types | 4 ++-- ...genericCallWithConstraintsTypeArgumentInference2.types | 8 ++++---- .../genericCallWithObjectTypeArgsAndConstraints4.types | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/fillInMissingTypeArgsOnConstructCalls.types b/tests/baselines/reference/fillInMissingTypeArgsOnConstructCalls.types index 7a5f49d638f61..b98b8a30e477b 100644 --- a/tests/baselines/reference/fillInMissingTypeArgsOnConstructCalls.types +++ b/tests/baselines/reference/fillInMissingTypeArgsOnConstructCalls.types @@ -6,7 +6,7 @@ class A{ >list : T } var a = new A(); ->a : A<{}> ->new A() : A<{}> +>a : A +>new A() : A >A : typeof A diff --git a/tests/baselines/reference/genericCallWithConstraintsTypeArgumentInference2.types b/tests/baselines/reference/genericCallWithConstraintsTypeArgumentInference2.types index cfd9e24182bec..23a2a5651a40b 100644 --- a/tests/baselines/reference/genericCallWithConstraintsTypeArgumentInference2.types +++ b/tests/baselines/reference/genericCallWithConstraintsTypeArgumentInference2.types @@ -19,14 +19,14 @@ var r = foo(1); // ok >1 : 1 var r2 = foo(null); // {} ->r2 : {} ->foo(null) : {} +>r2 : any +>foo(null) : any >foo : (t: T) => U >null : null var r3 = foo(new Object()); // {} ->r3 : {} ->foo(new Object()) : {} +>r3 : Object +>foo(new Object()) : Object >foo : (t: T) => U >new Object() : Object >Object : ObjectConstructor diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints4.types b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints4.types index 4c058c8a265bf..bffffbd102138 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints4.types +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints4.types @@ -96,11 +96,11 @@ var r8 = foo(() => { }, () => { }); >() => { } : () => void var r9 = foo(() => { }, () => 1); ->r9 : (x: () => void) => () => 1 ->foo(() => { }, () => 1) : (x: () => void) => () => 1 +>r9 : (x: () => void) => () => number +>foo(() => { }, () => 1) : (x: () => void) => () => number >foo : (t: T, t2: U) => (x: T) => U >() => { } : () => void ->() => 1 : () => 1 +>() => 1 : () => number >1 : 1 function other() { From 887b30682bf377e28826fbeafc5abdbebf5e5e77 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 24 Mar 2019 11:34:14 -0700 Subject: [PATCH 4/6] Add tests --- .../compiler/instantiateContextualTypes.ts | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 tests/cases/compiler/instantiateContextualTypes.ts diff --git a/tests/cases/compiler/instantiateContextualTypes.ts b/tests/cases/compiler/instantiateContextualTypes.ts new file mode 100644 index 0000000000000..b81356fa91ec9 --- /dev/null +++ b/tests/cases/compiler/instantiateContextualTypes.ts @@ -0,0 +1,142 @@ +// @strict: true +// @target: es6 + +// #6611 + +export interface A { + value: a; +} + +function fn(values: A, value: a) : void { +} + +declare let handlers: A<(value: number) => void>; +fn(handlers, value => alert(value)); + +// #21382 + +interface BaseProps { + initialValues: T; + nextValues: (cur: T) => T; +} +declare class Component

{ constructor(props: P); props: P; } +declare class GenericComponent + extends Component> { + iv: Values; +} + +new GenericComponent({ initialValues: 12, nextValues: val => 12 }); + +// #22149 + +declare function useStringOrNumber(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void; +useStringOrNumber("", foo => {}); + +// #25299 + +type ActionType

= string & { attachPayloadTypeHack?: P & never } + +type Handler = P extends void + ? (state: S) => S + : (state: S, payload: P) => S + +interface ActionHandler { + actionType: ActionType

+ handler: Handler +} + +declare function handler(actionType: ActionType

, handler: Handler): ActionHandler + +declare function createReducer( + defaultState: S, + ...actionHandlers: ActionHandler[] + ): any + +interface AppState { + dummy: string +} + +const defaultState: AppState = { + dummy: '' +} + +const NON_VOID_ACTION: ActionType = 'NON_VOID_ACTION' + , VOID_ACTION: ActionType = 'VOID_ACTION' + +createReducer( + defaultState, + handler(NON_VOID_ACTION, (state, _payload) => state), + handler(VOID_ACTION, state => state) +) + +// #25814 + +type R = { + a: (x: number) => void; + b: (x: string) => void; +}; + +type O = { + on

(x: P, callback: R[P]): void; +}; + +declare var x: O; +x.on('a', a => {}); + +// #29775 + +namespace N1 { + +declare class Component

{ + constructor(props: P); +} + +interface ComponentClass

{ + new (props: P): Component

; +} + +type CreateElementChildren

= + P extends { children?: infer C } + ? C extends any[] + ? C + : C[] + : unknown; + +declare function createElement

( + type: ComponentClass

, + ...children: CreateElementChildren

+): any; + +declare function createElement2

( + type: ComponentClass

, + child: CreateElementChildren

+): any; + +class InferFunctionTypes extends Component<{children: (foo: number) => string}> {} + +createElement(InferFunctionTypes, (foo) => "" + foo); + +createElement2(InferFunctionTypes, [(foo) => "" + foo]); + +} + +// #30341 + +type InnerBox = { + value: T; +} + +type OuterBox = { + inner: InnerBox +}; + +type BoxConsumerFromOuterBox = + T extends OuterBox ? + (box: InnerBox) => void : + never; + +declare function passContentsToFunc(outerBox: T, consumer: BoxConsumerFromOuterBox): void; + +declare const outerBoxOfString: OuterBox; + +passContentsToFunc(outerBoxOfString, box => box.value); From de76d55ddd0274fee53b07753d6d2fdad8861fbc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 24 Mar 2019 11:34:22 -0700 Subject: [PATCH 5/6] Accept new baselines --- .../reference/instantiateContextualTypes.js | 164 +++++++ .../instantiateContextualTypes.symbols | 409 ++++++++++++++++++ .../instantiateContextualTypes.types | 328 ++++++++++++++ 3 files changed, 901 insertions(+) create mode 100644 tests/baselines/reference/instantiateContextualTypes.js create mode 100644 tests/baselines/reference/instantiateContextualTypes.symbols create mode 100644 tests/baselines/reference/instantiateContextualTypes.types diff --git a/tests/baselines/reference/instantiateContextualTypes.js b/tests/baselines/reference/instantiateContextualTypes.js new file mode 100644 index 0000000000000..3a33b54278cd8 --- /dev/null +++ b/tests/baselines/reference/instantiateContextualTypes.js @@ -0,0 +1,164 @@ +//// [instantiateContextualTypes.ts] +// #6611 + +export interface A { + value: a; +} + +function fn(values: A, value: a) : void { +} + +declare let handlers: A<(value: number) => void>; +fn(handlers, value => alert(value)); + +// #21382 + +interface BaseProps { + initialValues: T; + nextValues: (cur: T) => T; +} +declare class Component

{ constructor(props: P); props: P; } +declare class GenericComponent + extends Component> { + iv: Values; +} + +new GenericComponent({ initialValues: 12, nextValues: val => 12 }); + +// #22149 + +declare function useStringOrNumber(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void; +useStringOrNumber("", foo => {}); + +// #25299 + +type ActionType

= string & { attachPayloadTypeHack?: P & never } + +type Handler = P extends void + ? (state: S) => S + : (state: S, payload: P) => S + +interface ActionHandler { + actionType: ActionType

+ handler: Handler +} + +declare function handler(actionType: ActionType

, handler: Handler): ActionHandler + +declare function createReducer( + defaultState: S, + ...actionHandlers: ActionHandler[] + ): any + +interface AppState { + dummy: string +} + +const defaultState: AppState = { + dummy: '' +} + +const NON_VOID_ACTION: ActionType = 'NON_VOID_ACTION' + , VOID_ACTION: ActionType = 'VOID_ACTION' + +createReducer( + defaultState, + handler(NON_VOID_ACTION, (state, _payload) => state), + handler(VOID_ACTION, state => state) +) + +// #25814 + +type R = { + a: (x: number) => void; + b: (x: string) => void; +}; + +type O = { + on

(x: P, callback: R[P]): void; +}; + +declare var x: O; +x.on('a', a => {}); + +// #29775 + +namespace N1 { + +declare class Component

{ + constructor(props: P); +} + +interface ComponentClass

{ + new (props: P): Component

; +} + +type CreateElementChildren

= + P extends { children?: infer C } + ? C extends any[] + ? C + : C[] + : unknown; + +declare function createElement

( + type: ComponentClass

, + ...children: CreateElementChildren

+): any; + +declare function createElement2

( + type: ComponentClass

, + child: CreateElementChildren

+): any; + +class InferFunctionTypes extends Component<{children: (foo: number) => string}> {} + +createElement(InferFunctionTypes, (foo) => "" + foo); + +createElement2(InferFunctionTypes, [(foo) => "" + foo]); + +} + +// #30341 + +type InnerBox = { + value: T; +} + +type OuterBox = { + inner: InnerBox +}; + +type BoxConsumerFromOuterBox = + T extends OuterBox ? + (box: InnerBox) => void : + never; + +declare function passContentsToFunc(outerBox: T, consumer: BoxConsumerFromOuterBox): void; + +declare const outerBoxOfString: OuterBox; + +passContentsToFunc(outerBoxOfString, box => box.value); + + +//// [instantiateContextualTypes.js] +// #6611 +function fn(values, value) { +} +fn(handlers, value => alert(value)); +new GenericComponent({ initialValues: 12, nextValues: val => 12 }); +useStringOrNumber("", foo => { }); +const defaultState = { + dummy: '' +}; +const NON_VOID_ACTION = 'NON_VOID_ACTION', VOID_ACTION = 'VOID_ACTION'; +createReducer(defaultState, handler(NON_VOID_ACTION, (state, _payload) => state), handler(VOID_ACTION, state => state)); +x.on('a', a => { }); +// #29775 +var N1; +(function (N1) { + class InferFunctionTypes extends Component { + } + createElement(InferFunctionTypes, (foo) => "" + foo); + createElement2(InferFunctionTypes, [(foo) => "" + foo]); +})(N1 || (N1 = {})); +passContentsToFunc(outerBoxOfString, box => box.value); diff --git a/tests/baselines/reference/instantiateContextualTypes.symbols b/tests/baselines/reference/instantiateContextualTypes.symbols new file mode 100644 index 0000000000000..098be95bac50c --- /dev/null +++ b/tests/baselines/reference/instantiateContextualTypes.symbols @@ -0,0 +1,409 @@ +=== tests/cases/compiler/instantiateContextualTypes.ts === +// #6611 + +export interface A { +>A : Symbol(A, Decl(instantiateContextualTypes.ts, 0, 0)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 2, 19)) + + value: a; +>value : Symbol(A.value, Decl(instantiateContextualTypes.ts, 2, 23)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 2, 19)) +} + +function fn(values: A, value: a) : void { +>fn : Symbol(fn, Decl(instantiateContextualTypes.ts, 4, 1)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 6, 12)) +>values : Symbol(values, Decl(instantiateContextualTypes.ts, 6, 15)) +>A : Symbol(A, Decl(instantiateContextualTypes.ts, 0, 0)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 6, 12)) +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 6, 28)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 6, 12)) +} + +declare let handlers: A<(value: number) => void>; +>handlers : Symbol(handlers, Decl(instantiateContextualTypes.ts, 9, 11)) +>A : Symbol(A, Decl(instantiateContextualTypes.ts, 0, 0)) +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 9, 25)) + +fn(handlers, value => alert(value)); +>fn : Symbol(fn, Decl(instantiateContextualTypes.ts, 4, 1)) +>handlers : Symbol(handlers, Decl(instantiateContextualTypes.ts, 9, 11)) +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 10, 12)) +>alert : Symbol(alert, Decl(lib.dom.d.ts, --, --)) +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 10, 12)) + +// #21382 + +interface BaseProps { +>BaseProps : Symbol(BaseProps, Decl(instantiateContextualTypes.ts, 10, 36)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 14, 20)) + + initialValues: T; +>initialValues : Symbol(BaseProps.initialValues, Decl(instantiateContextualTypes.ts, 14, 24)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 14, 20)) + + nextValues: (cur: T) => T; +>nextValues : Symbol(BaseProps.nextValues, Decl(instantiateContextualTypes.ts, 15, 19)) +>cur : Symbol(cur, Decl(instantiateContextualTypes.ts, 16, 15)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 14, 20)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 14, 20)) +} +declare class Component

{ constructor(props: P); props: P; } +>Component : Symbol(Component, Decl(instantiateContextualTypes.ts, 17, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 18, 24)) +>props : Symbol(props, Decl(instantiateContextualTypes.ts, 18, 41)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 18, 24)) +>props : Symbol(Component.props, Decl(instantiateContextualTypes.ts, 18, 51)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 18, 24)) + +declare class GenericComponent +>GenericComponent : Symbol(GenericComponent, Decl(instantiateContextualTypes.ts, 18, 63)) +>Props : Symbol(Props, Decl(instantiateContextualTypes.ts, 19, 31)) +>Values : Symbol(Values, Decl(instantiateContextualTypes.ts, 19, 42)) + + extends Component> { +>Component : Symbol(Component, Decl(instantiateContextualTypes.ts, 17, 1)) +>Props : Symbol(Props, Decl(instantiateContextualTypes.ts, 19, 31)) +>BaseProps : Symbol(BaseProps, Decl(instantiateContextualTypes.ts, 10, 36)) +>Values : Symbol(Values, Decl(instantiateContextualTypes.ts, 19, 42)) + + iv: Values; +>iv : Symbol(GenericComponent.iv, Decl(instantiateContextualTypes.ts, 20, 50)) +>Values : Symbol(Values, Decl(instantiateContextualTypes.ts, 19, 42)) +} + +new GenericComponent({ initialValues: 12, nextValues: val => 12 }); +>GenericComponent : Symbol(GenericComponent, Decl(instantiateContextualTypes.ts, 18, 63)) +>initialValues : Symbol(initialValues, Decl(instantiateContextualTypes.ts, 24, 22)) +>nextValues : Symbol(nextValues, Decl(instantiateContextualTypes.ts, 24, 41)) +>val : Symbol(val, Decl(instantiateContextualTypes.ts, 24, 53)) + +// #22149 + +declare function useStringOrNumber(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void; +>useStringOrNumber : Symbol(useStringOrNumber, Decl(instantiateContextualTypes.ts, 24, 67)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 28, 35)) +>t : Symbol(t, Decl(instantiateContextualTypes.ts, 28, 62)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 28, 35)) +>useIt : Symbol(useIt, Decl(instantiateContextualTypes.ts, 28, 67)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 28, 35)) +>s : Symbol(s, Decl(instantiateContextualTypes.ts, 28, 96)) +>n : Symbol(n, Decl(instantiateContextualTypes.ts, 28, 120)) + +useStringOrNumber("", foo => {}); +>useStringOrNumber : Symbol(useStringOrNumber, Decl(instantiateContextualTypes.ts, 24, 67)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 29, 21)) + +// #25299 + +type ActionType

= string & { attachPayloadTypeHack?: P & never } +>ActionType : Symbol(ActionType, Decl(instantiateContextualTypes.ts, 29, 33)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 33, 16)) +>attachPayloadTypeHack : Symbol(attachPayloadTypeHack, Decl(instantiateContextualTypes.ts, 33, 31)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 33, 16)) + +type Handler = P extends void +>Handler : Symbol(Handler, Decl(instantiateContextualTypes.ts, 33, 67)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 35, 13)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 35, 15)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 35, 15)) + + ? (state: S) => S +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 36, 7)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 35, 13)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 35, 13)) + + : (state: S, payload: P) => S +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 37, 7)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 35, 13)) +>payload : Symbol(payload, Decl(instantiateContextualTypes.ts, 37, 16)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 35, 15)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 35, 13)) + +interface ActionHandler { +>ActionHandler : Symbol(ActionHandler, Decl(instantiateContextualTypes.ts, 37, 33)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 39, 24)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 39, 26)) + + actionType: ActionType

+>actionType : Symbol(ActionHandler.actionType, Decl(instantiateContextualTypes.ts, 39, 31)) +>ActionType : Symbol(ActionType, Decl(instantiateContextualTypes.ts, 29, 33)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 39, 26)) + + handler: Handler +>handler : Symbol(ActionHandler.handler, Decl(instantiateContextualTypes.ts, 40, 29)) +>Handler : Symbol(Handler, Decl(instantiateContextualTypes.ts, 33, 67)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 39, 24)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 39, 26)) +} + +declare function handler(actionType: ActionType

, handler: Handler): ActionHandler +>handler : Symbol(handler, Decl(instantiateContextualTypes.ts, 42, 1)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 44, 25)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 44, 27)) +>actionType : Symbol(actionType, Decl(instantiateContextualTypes.ts, 44, 31)) +>ActionType : Symbol(ActionType, Decl(instantiateContextualTypes.ts, 29, 33)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 44, 27)) +>handler : Symbol(handler, Decl(instantiateContextualTypes.ts, 44, 57)) +>Handler : Symbol(Handler, Decl(instantiateContextualTypes.ts, 33, 67)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 44, 25)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 44, 27)) +>ActionHandler : Symbol(ActionHandler, Decl(instantiateContextualTypes.ts, 37, 33)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 44, 25)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 44, 27)) + +declare function createReducer( +>createReducer : Symbol(createReducer, Decl(instantiateContextualTypes.ts, 44, 102)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 46, 31)) + + defaultState: S, +>defaultState : Symbol(defaultState, Decl(instantiateContextualTypes.ts, 46, 34)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 46, 31)) + + ...actionHandlers: ActionHandler[] +>actionHandlers : Symbol(actionHandlers, Decl(instantiateContextualTypes.ts, 47, 24)) +>ActionHandler : Symbol(ActionHandler, Decl(instantiateContextualTypes.ts, 37, 33)) +>S : Symbol(S, Decl(instantiateContextualTypes.ts, 46, 31)) + + ): any + +interface AppState { +>AppState : Symbol(AppState, Decl(instantiateContextualTypes.ts, 49, 10)) + + dummy: string +>dummy : Symbol(AppState.dummy, Decl(instantiateContextualTypes.ts, 51, 20)) +} + +const defaultState: AppState = { +>defaultState : Symbol(defaultState, Decl(instantiateContextualTypes.ts, 55, 5)) +>AppState : Symbol(AppState, Decl(instantiateContextualTypes.ts, 49, 10)) + + dummy: '' +>dummy : Symbol(dummy, Decl(instantiateContextualTypes.ts, 55, 32)) +} + +const NON_VOID_ACTION: ActionType = 'NON_VOID_ACTION' +>NON_VOID_ACTION : Symbol(NON_VOID_ACTION, Decl(instantiateContextualTypes.ts, 59, 5)) +>ActionType : Symbol(ActionType, Decl(instantiateContextualTypes.ts, 29, 33)) + + , VOID_ACTION: ActionType = 'VOID_ACTION' +>VOID_ACTION : Symbol(VOID_ACTION, Decl(instantiateContextualTypes.ts, 60, 5)) +>ActionType : Symbol(ActionType, Decl(instantiateContextualTypes.ts, 29, 33)) + +createReducer( +>createReducer : Symbol(createReducer, Decl(instantiateContextualTypes.ts, 44, 102)) + + defaultState, +>defaultState : Symbol(defaultState, Decl(instantiateContextualTypes.ts, 55, 5)) + + handler(NON_VOID_ACTION, (state, _payload) => state), +>handler : Symbol(handler, Decl(instantiateContextualTypes.ts, 42, 1)) +>NON_VOID_ACTION : Symbol(NON_VOID_ACTION, Decl(instantiateContextualTypes.ts, 59, 5)) +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 64, 30)) +>_payload : Symbol(_payload, Decl(instantiateContextualTypes.ts, 64, 36)) +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 64, 30)) + + handler(VOID_ACTION, state => state) +>handler : Symbol(handler, Decl(instantiateContextualTypes.ts, 42, 1)) +>VOID_ACTION : Symbol(VOID_ACTION, Decl(instantiateContextualTypes.ts, 60, 5)) +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 65, 24)) +>state : Symbol(state, Decl(instantiateContextualTypes.ts, 65, 24)) + +) + +// #25814 + +type R = { +>R : Symbol(R, Decl(instantiateContextualTypes.ts, 66, 1)) + + a: (x: number) => void; +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 70, 10)) +>x : Symbol(x, Decl(instantiateContextualTypes.ts, 71, 6)) + + b: (x: string) => void; +>b : Symbol(b, Decl(instantiateContextualTypes.ts, 71, 25)) +>x : Symbol(x, Decl(instantiateContextualTypes.ts, 72, 6)) + +}; + +type O = { +>O : Symbol(O, Decl(instantiateContextualTypes.ts, 73, 2)) + + on

(x: P, callback: R[P]): void; +>on : Symbol(on, Decl(instantiateContextualTypes.ts, 75, 10)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 76, 5)) +>R : Symbol(R, Decl(instantiateContextualTypes.ts, 66, 1)) +>x : Symbol(x, Decl(instantiateContextualTypes.ts, 76, 24)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 76, 5)) +>callback : Symbol(callback, Decl(instantiateContextualTypes.ts, 76, 29)) +>R : Symbol(R, Decl(instantiateContextualTypes.ts, 66, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 76, 5)) + +}; + +declare var x: O; +>x : Symbol(x, Decl(instantiateContextualTypes.ts, 79, 11)) +>O : Symbol(O, Decl(instantiateContextualTypes.ts, 73, 2)) + +x.on('a', a => {}); +>x.on : Symbol(on, Decl(instantiateContextualTypes.ts, 75, 10)) +>x : Symbol(x, Decl(instantiateContextualTypes.ts, 79, 11)) +>on : Symbol(on, Decl(instantiateContextualTypes.ts, 75, 10)) +>a : Symbol(a, Decl(instantiateContextualTypes.ts, 80, 9)) + +// #29775 + +namespace N1 { +>N1 : Symbol(N1, Decl(instantiateContextualTypes.ts, 80, 19)) + +declare class Component

{ +>Component : Symbol(Component, Decl(instantiateContextualTypes.ts, 84, 14)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 86, 24)) + + constructor(props: P); +>props : Symbol(props, Decl(instantiateContextualTypes.ts, 87, 14)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 86, 24)) +} + +interface ComponentClass

{ +>ComponentClass : Symbol(ComponentClass, Decl(instantiateContextualTypes.ts, 88, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 90, 25)) + + new (props: P): Component

; +>props : Symbol(props, Decl(instantiateContextualTypes.ts, 91, 7)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 90, 25)) +>Component : Symbol(Component, Decl(instantiateContextualTypes.ts, 84, 14)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 90, 25)) +} + +type CreateElementChildren

= +>CreateElementChildren : Symbol(CreateElementChildren, Decl(instantiateContextualTypes.ts, 92, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 94, 27)) + + P extends { children?: infer C } +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 94, 27)) +>children : Symbol(children, Decl(instantiateContextualTypes.ts, 95, 13)) +>C : Symbol(C, Decl(instantiateContextualTypes.ts, 95, 30)) + + ? C extends any[] +>C : Symbol(C, Decl(instantiateContextualTypes.ts, 95, 30)) + + ? C +>C : Symbol(C, Decl(instantiateContextualTypes.ts, 95, 30)) + + : C[] +>C : Symbol(C, Decl(instantiateContextualTypes.ts, 95, 30)) + + : unknown; + +declare function createElement

( +>createElement : Symbol(createElement, Decl(instantiateContextualTypes.ts, 99, 12)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 101, 31)) + + type: ComponentClass

, +>type : Symbol(type, Decl(instantiateContextualTypes.ts, 101, 45)) +>ComponentClass : Symbol(ComponentClass, Decl(instantiateContextualTypes.ts, 88, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 101, 31)) + + ...children: CreateElementChildren

+>children : Symbol(children, Decl(instantiateContextualTypes.ts, 102, 26)) +>CreateElementChildren : Symbol(CreateElementChildren, Decl(instantiateContextualTypes.ts, 92, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 101, 31)) + +): any; + +declare function createElement2

( +>createElement2 : Symbol(createElement2, Decl(instantiateContextualTypes.ts, 104, 7)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 106, 32)) + + type: ComponentClass

, +>type : Symbol(type, Decl(instantiateContextualTypes.ts, 106, 46)) +>ComponentClass : Symbol(ComponentClass, Decl(instantiateContextualTypes.ts, 88, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 106, 32)) + + child: CreateElementChildren

+>child : Symbol(child, Decl(instantiateContextualTypes.ts, 107, 26)) +>CreateElementChildren : Symbol(CreateElementChildren, Decl(instantiateContextualTypes.ts, 92, 1)) +>P : Symbol(P, Decl(instantiateContextualTypes.ts, 106, 32)) + +): any; + +class InferFunctionTypes extends Component<{children: (foo: number) => string}> {} +>InferFunctionTypes : Symbol(InferFunctionTypes, Decl(instantiateContextualTypes.ts, 109, 7)) +>Component : Symbol(Component, Decl(instantiateContextualTypes.ts, 84, 14)) +>children : Symbol(children, Decl(instantiateContextualTypes.ts, 111, 44)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 111, 55)) + +createElement(InferFunctionTypes, (foo) => "" + foo); +>createElement : Symbol(createElement, Decl(instantiateContextualTypes.ts, 99, 12)) +>InferFunctionTypes : Symbol(InferFunctionTypes, Decl(instantiateContextualTypes.ts, 109, 7)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 113, 35)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 113, 35)) + +createElement2(InferFunctionTypes, [(foo) => "" + foo]); +>createElement2 : Symbol(createElement2, Decl(instantiateContextualTypes.ts, 104, 7)) +>InferFunctionTypes : Symbol(InferFunctionTypes, Decl(instantiateContextualTypes.ts, 109, 7)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 115, 37)) +>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 115, 37)) + +} + +// #30341 + +type InnerBox = { +>InnerBox : Symbol(InnerBox, Decl(instantiateContextualTypes.ts, 117, 1)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 121, 14)) + + value: T; +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 121, 20)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 121, 14)) +} + +type OuterBox = { +>OuterBox : Symbol(OuterBox, Decl(instantiateContextualTypes.ts, 123, 1)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 125, 14)) + + inner: InnerBox +>inner : Symbol(inner, Decl(instantiateContextualTypes.ts, 125, 20)) +>InnerBox : Symbol(InnerBox, Decl(instantiateContextualTypes.ts, 117, 1)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 125, 14)) + +}; + +type BoxConsumerFromOuterBox = +>BoxConsumerFromOuterBox : Symbol(BoxConsumerFromOuterBox, Decl(instantiateContextualTypes.ts, 127, 2)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 129, 29)) + + T extends OuterBox ? +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 129, 29)) +>OuterBox : Symbol(OuterBox, Decl(instantiateContextualTypes.ts, 123, 1)) +>U : Symbol(U, Decl(instantiateContextualTypes.ts, 130, 26)) + + (box: InnerBox) => void : +>box : Symbol(box, Decl(instantiateContextualTypes.ts, 131, 7)) +>InnerBox : Symbol(InnerBox, Decl(instantiateContextualTypes.ts, 117, 1)) +>U : Symbol(U, Decl(instantiateContextualTypes.ts, 130, 26)) + + never; + +declare function passContentsToFunc(outerBox: T, consumer: BoxConsumerFromOuterBox): void; +>passContentsToFunc : Symbol(passContentsToFunc, Decl(instantiateContextualTypes.ts, 132, 12)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 134, 36)) +>outerBox : Symbol(outerBox, Decl(instantiateContextualTypes.ts, 134, 39)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 134, 36)) +>consumer : Symbol(consumer, Decl(instantiateContextualTypes.ts, 134, 51)) +>BoxConsumerFromOuterBox : Symbol(BoxConsumerFromOuterBox, Decl(instantiateContextualTypes.ts, 127, 2)) +>T : Symbol(T, Decl(instantiateContextualTypes.ts, 134, 36)) + +declare const outerBoxOfString: OuterBox; +>outerBoxOfString : Symbol(outerBoxOfString, Decl(instantiateContextualTypes.ts, 136, 13)) +>OuterBox : Symbol(OuterBox, Decl(instantiateContextualTypes.ts, 123, 1)) + +passContentsToFunc(outerBoxOfString, box => box.value); +>passContentsToFunc : Symbol(passContentsToFunc, Decl(instantiateContextualTypes.ts, 132, 12)) +>outerBoxOfString : Symbol(outerBoxOfString, Decl(instantiateContextualTypes.ts, 136, 13)) +>box : Symbol(box, Decl(instantiateContextualTypes.ts, 138, 36)) +>box.value : Symbol(value, Decl(instantiateContextualTypes.ts, 121, 20)) +>box : Symbol(box, Decl(instantiateContextualTypes.ts, 138, 36)) +>value : Symbol(value, Decl(instantiateContextualTypes.ts, 121, 20)) + diff --git a/tests/baselines/reference/instantiateContextualTypes.types b/tests/baselines/reference/instantiateContextualTypes.types new file mode 100644 index 0000000000000..0e755e82ed308 --- /dev/null +++ b/tests/baselines/reference/instantiateContextualTypes.types @@ -0,0 +1,328 @@ +=== tests/cases/compiler/instantiateContextualTypes.ts === +// #6611 + +export interface A { + value: a; +>value : a +} + +function fn(values: A, value: a) : void { +>fn : (values: A, value: a) => void +>values : A +>value : a +} + +declare let handlers: A<(value: number) => void>; +>handlers : A<(value: number) => void> +>value : number + +fn(handlers, value => alert(value)); +>fn(handlers, value => alert(value)) : void +>fn : (values: A, value: a) => void +>handlers : A<(value: number) => void> +>value => alert(value) : (value: number) => void +>value : number +>alert(value) : void +>alert : (message?: any) => void +>value : number + +// #21382 + +interface BaseProps { + initialValues: T; +>initialValues : T + + nextValues: (cur: T) => T; +>nextValues : (cur: T) => T +>cur : T +} +declare class Component

{ constructor(props: P); props: P; } +>Component : Component

+>props : P +>props : P + +declare class GenericComponent +>GenericComponent : GenericComponent + + extends Component> { +>Component : Component> + + iv: Values; +>iv : Values +} + +new GenericComponent({ initialValues: 12, nextValues: val => 12 }); +>new GenericComponent({ initialValues: 12, nextValues: val => 12 }) : GenericComponent<{ initialValues: number; nextValues: (val: number) => number; }, number> +>GenericComponent : typeof GenericComponent +>{ initialValues: 12, nextValues: val => 12 } : { initialValues: number; nextValues: (val: number) => number; } +>initialValues : number +>12 : 12 +>nextValues : (val: number) => number +>val => 12 : (val: number) => number +>val : number +>12 : 12 + +// #22149 + +declare function useStringOrNumber(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void; +>useStringOrNumber : (t: T, useIt: T extends string ? (s: string) => void : (n: number) => void) => void +>t : T +>useIt : T extends string ? (s: string) => void : (n: number) => void +>s : string +>n : number + +useStringOrNumber("", foo => {}); +>useStringOrNumber("", foo => {}) : void +>useStringOrNumber : (t: T, useIt: T extends string ? (s: string) => void : (n: number) => void) => void +>"" : "" +>foo => {} : (foo: string) => void +>foo : string + +// #25299 + +type ActionType

= string & { attachPayloadTypeHack?: P & never } +>ActionType : ActionType

+>attachPayloadTypeHack : undefined + +type Handler = P extends void +>Handler : Handler + + ? (state: S) => S +>state : S + + : (state: S, payload: P) => S +>state : S +>payload : P + +interface ActionHandler { + actionType: ActionType

+>actionType : ActionType

+ + handler: Handler +>handler : Handler +} + +declare function handler(actionType: ActionType

, handler: Handler): ActionHandler +>handler : (actionType: ActionType

, handler: Handler) => ActionHandler +>actionType : ActionType

+>handler : Handler + +declare function createReducer( +>createReducer : (defaultState: S, ...actionHandlers: ActionHandler[]) => any + + defaultState: S, +>defaultState : S + + ...actionHandlers: ActionHandler[] +>actionHandlers : ActionHandler[] + + ): any + +interface AppState { + dummy: string +>dummy : string +} + +const defaultState: AppState = { +>defaultState : AppState +>{ dummy: ''} : { dummy: string; } + + dummy: '' +>dummy : string +>'' : "" +} + +const NON_VOID_ACTION: ActionType = 'NON_VOID_ACTION' +>NON_VOID_ACTION : ActionType +>'NON_VOID_ACTION' : "NON_VOID_ACTION" + + , VOID_ACTION: ActionType = 'VOID_ACTION' +>VOID_ACTION : ActionType +>'VOID_ACTION' : "VOID_ACTION" + +createReducer( +>createReducer( defaultState, handler(NON_VOID_ACTION, (state, _payload) => state), handler(VOID_ACTION, state => state)) : any +>createReducer : (defaultState: S, ...actionHandlers: ActionHandler[]) => any + + defaultState, +>defaultState : AppState + + handler(NON_VOID_ACTION, (state, _payload) => state), +>handler(NON_VOID_ACTION, (state, _payload) => state) : ActionHandler +>handler : (actionType: ActionType

, handler: Handler) => ActionHandler +>NON_VOID_ACTION : ActionType +>(state, _payload) => state : (state: AppState, _payload: number) => AppState +>state : AppState +>_payload : number +>state : AppState + + handler(VOID_ACTION, state => state) +>handler(VOID_ACTION, state => state) : ActionHandler +>handler : (actionType: ActionType

, handler: Handler) => ActionHandler +>VOID_ACTION : ActionType +>state => state : (state: AppState) => AppState +>state : AppState +>state : AppState + +) + +// #25814 + +type R = { +>R : R + + a: (x: number) => void; +>a : (x: number) => void +>x : number + + b: (x: string) => void; +>b : (x: string) => void +>x : string + +}; + +type O = { +>O : O + + on

(x: P, callback: R[P]): void; +>on :

(x: P, callback: R[P]) => void +>x : P +>callback : R[P] + +}; + +declare var x: O; +>x : O + +x.on('a', a => {}); +>x.on('a', a => {}) : void +>x.on :

(x: P, callback: R[P]) => void +>x : O +>on :

(x: P, callback: R[P]) => void +>'a' : "a" +>a => {} : (a: number) => void +>a : number + +// #29775 + +namespace N1 { +>N1 : typeof N1 + +declare class Component

{ +>Component : Component

+ + constructor(props: P); +>props : P +} + +interface ComponentClass

{ + new (props: P): Component

; +>props : P +} + +type CreateElementChildren

= +>CreateElementChildren : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown + + P extends { children?: infer C } +>children : C | undefined + + ? C extends any[] + ? C + : C[] + : unknown; + +declare function createElement

( +>createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any + + type: ComponentClass

, +>type : ComponentClass

+ + ...children: CreateElementChildren

+>children : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown + +): any; + +declare function createElement2

( +>createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any + + type: ComponentClass

, +>type : ComponentClass

+ + child: CreateElementChildren

+>child : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown + +): any; + +class InferFunctionTypes extends Component<{children: (foo: number) => string}> {} +>InferFunctionTypes : InferFunctionTypes +>Component : Component<{ children: (foo: number) => string; }> +>children : (foo: number) => string +>foo : number + +createElement(InferFunctionTypes, (foo) => "" + foo); +>createElement(InferFunctionTypes, (foo) => "" + foo) : any +>createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>InferFunctionTypes : typeof InferFunctionTypes +>(foo) => "" + foo : (foo: number) => string +>foo : number +>"" + foo : string +>"" : "" +>foo : number + +createElement2(InferFunctionTypes, [(foo) => "" + foo]); +>createElement2(InferFunctionTypes, [(foo) => "" + foo]) : any +>createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>InferFunctionTypes : typeof InferFunctionTypes +>[(foo) => "" + foo] : ((foo: number) => string)[] +>(foo) => "" + foo : (foo: number) => string +>foo : number +>"" + foo : string +>"" : "" +>foo : number + +} + +// #30341 + +type InnerBox = { +>InnerBox : InnerBox + + value: T; +>value : T +} + +type OuterBox = { +>OuterBox : OuterBox + + inner: InnerBox +>inner : InnerBox + +}; + +type BoxConsumerFromOuterBox = +>BoxConsumerFromOuterBox : BoxConsumerFromOuterBox + + T extends OuterBox ? + (box: InnerBox) => void : +>box : InnerBox + + never; + +declare function passContentsToFunc(outerBox: T, consumer: BoxConsumerFromOuterBox): void; +>passContentsToFunc : (outerBox: T, consumer: BoxConsumerFromOuterBox) => void +>outerBox : T +>consumer : BoxConsumerFromOuterBox + +declare const outerBoxOfString: OuterBox; +>outerBoxOfString : OuterBox + +passContentsToFunc(outerBoxOfString, box => box.value); +>passContentsToFunc(outerBoxOfString, box => box.value) : void +>passContentsToFunc : (outerBox: T, consumer: BoxConsumerFromOuterBox) => void +>outerBoxOfString : OuterBox +>box => box.value : (box: InnerBox) => string +>box : InnerBox +>box.value : string +>box : InnerBox +>value : string + From fca46bb7061ff5f8c6875e589faf8a8b35ef720c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 26 Mar 2019 07:00:19 -0700 Subject: [PATCH 6/6] Compute per-element contextual type in getSpreadArgumentType --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 26727e82c635c..2fd72ed40ef25 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20264,15 +20264,15 @@ namespace ts { getArrayifiedType(checkExpressionWithContextualType((arg).expression, restType, context, CheckMode.Normal)); } } - const contextualType = getIndexedAccessType(restType, numberType); - const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index); const types = []; let spreadIndex = -1; for (let i = index; i < argCount; i++) { + const contextualType = getIndexedAccessType(restType, getLiteralType(i - index)); const argType = checkExpressionWithContextualType(args[i], contextualType, context, CheckMode.Normal); if (spreadIndex < 0 && isSpreadArgument(args[i])) { spreadIndex = i - index; } + const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index); types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); } return spreadIndex < 0 ?