mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-01 13:04:42 -05:00
Merge pull request #30568 from Microsoft/instantiateContextualTypes
Contextual typing based on instantiated types
This commit is contained in:
@@ -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,
|
||||
@@ -14495,7 +14500,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) {
|
||||
@@ -14539,7 +14544,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) {
|
||||
@@ -15041,8 +15046,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;
|
||||
@@ -15073,27 +15078,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 {
|
||||
@@ -17779,7 +17781,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getContextualTypeForBinaryOperand(node: Expression): Type | undefined {
|
||||
function getContextualTypeForBinaryOperand(node: Expression, contextFlags?: ContextFlags): Type | undefined {
|
||||
const binaryExpression = <BinaryExpression>node.parent;
|
||||
const { left, operatorToken, right } = binaryExpression;
|
||||
switch (operatorToken.kind) {
|
||||
@@ -17796,12 +17798,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;
|
||||
}
|
||||
@@ -17910,19 +17912,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 = <ObjectLiteralExpression>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
|
||||
@@ -17934,11 +17935,9 @@ namespace ts {
|
||||
return propertyType;
|
||||
}
|
||||
}
|
||||
|
||||
return isNumericName(element.name!) && getIndexTypeOfContextualType(type, IndexKind.Number) ||
|
||||
getIndexTypeOfContextualType(type, IndexKind.String);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -17953,9 +17952,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 = <ConditionalExpression>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) {
|
||||
@@ -18050,8 +18049,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) {
|
||||
@@ -18068,11 +18067,22 @@ 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 && inferenceContext.returnMapper) {
|
||||
return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contextualType;
|
||||
@@ -18111,7 +18121,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;
|
||||
@@ -18141,26 +18151,26 @@ namespace ts {
|
||||
case SyntaxKind.AsExpression:
|
||||
return isConstTypeReference((<AssertionExpression>parent).type) ? undefined : getTypeFromTypeNode((<AssertionExpression>parent).type);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return getContextualTypeForBinaryOperand(node);
|
||||
return getContextualTypeForBinaryOperand(node, contextFlags);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return getContextualTypeForObjectLiteralElement(<PropertyAssignment | ShorthandPropertyAssignment>parent);
|
||||
return getContextualTypeForObjectLiteralElement(<PropertyAssignment | ShorthandPropertyAssignment>parent, contextFlags);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression);
|
||||
return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression, contextFlags);
|
||||
case SyntaxKind.ArrayLiteralExpression: {
|
||||
const arrayLiteral = <ArrayLiteralExpression>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(<TemplateExpression>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(<ParenthesizedExpression>parent);
|
||||
return tag ? getTypeFromTypeNode(tag.typeExpression!.type) : getContextualType(<ParenthesizedExpression>parent, contextFlags);
|
||||
}
|
||||
case SyntaxKind.JsxExpression:
|
||||
return getContextualTypeForJsxExpression(<JsxExpression>parent);
|
||||
@@ -18351,12 +18361,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
|
||||
@@ -18368,7 +18372,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;
|
||||
}
|
||||
@@ -20275,7 +20281,7 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function getSpreadArgumentType(args: ReadonlyArray<Expression>, index: number, argCount: number, restType: TypeParameter, context: InferenceContext | undefined) {
|
||||
function getSpreadArgumentType(args: ReadonlyArray<Expression>, index: number, argCount: number, restType: Type, context: InferenceContext | undefined) {
|
||||
if (index >= argCount - 1) {
|
||||
const arg = args[argCount - 1];
|
||||
if (isSpreadArgument(arg)) {
|
||||
@@ -20286,15 +20292,15 @@ namespace ts {
|
||||
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context, CheckMode.Normal));
|
||||
}
|
||||
}
|
||||
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
|
||||
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 ?
|
||||
|
||||
@@ -6,7 +6,7 @@ class A<T extends Object>{
|
||||
>list : T
|
||||
}
|
||||
var a = new A();
|
||||
>a : A<{}>
|
||||
>new A() : A<{}>
|
||||
>a : A<Object>
|
||||
>new A() : A<Object>
|
||||
>A : typeof A
|
||||
|
||||
|
||||
@@ -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, U extends T>(t: T) => U
|
||||
>null : null
|
||||
|
||||
var r3 = foo(new Object()); // {}
|
||||
>r3 : {}
|
||||
>foo(new Object()) : {}
|
||||
>r3 : Object
|
||||
>foo(new Object()) : Object
|
||||
>foo : <T, U extends T>(t: T) => U
|
||||
>new Object() : Object
|
||||
>Object : ObjectConstructor
|
||||
|
||||
@@ -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, U extends T>(t: T, t2: U) => (x: T) => U
|
||||
>() => { } : () => void
|
||||
>() => 1 : () => 1
|
||||
>() => 1 : () => number
|
||||
>1 : 1
|
||||
|
||||
function other<T, U extends T>() {
|
||||
|
||||
164
tests/baselines/reference/instantiateContextualTypes.js
Normal file
164
tests/baselines/reference/instantiateContextualTypes.js
Normal file
@@ -0,0 +1,164 @@
|
||||
//// [instantiateContextualTypes.ts]
|
||||
// #6611
|
||||
|
||||
export interface A<a> {
|
||||
value: a;
|
||||
}
|
||||
|
||||
function fn<a>(values: A<a>, value: a) : void {
|
||||
}
|
||||
|
||||
declare let handlers: A<(value: number) => void>;
|
||||
fn(handlers, value => alert(value));
|
||||
|
||||
// #21382
|
||||
|
||||
interface BaseProps<T> {
|
||||
initialValues: T;
|
||||
nextValues: (cur: T) => T;
|
||||
}
|
||||
declare class Component<P> { constructor(props: P); props: P; }
|
||||
declare class GenericComponent<Props = {}, Values = object>
|
||||
extends Component<Props & BaseProps<Values>> {
|
||||
iv: Values;
|
||||
}
|
||||
|
||||
new GenericComponent({ initialValues: 12, nextValues: val => 12 });
|
||||
|
||||
// #22149
|
||||
|
||||
declare function useStringOrNumber<T extends string | number>(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void;
|
||||
useStringOrNumber("", foo => {});
|
||||
|
||||
// #25299
|
||||
|
||||
type ActionType<P> = string & { attachPayloadTypeHack?: P & never }
|
||||
|
||||
type Handler<S, P> = P extends void
|
||||
? (state: S) => S
|
||||
: (state: S, payload: P) => S
|
||||
|
||||
interface ActionHandler<S, P> {
|
||||
actionType: ActionType<P>
|
||||
handler: Handler<S, P>
|
||||
}
|
||||
|
||||
declare function handler<S, P>(actionType: ActionType<P>, handler: Handler<S, P>): ActionHandler<S, P>
|
||||
|
||||
declare function createReducer<S>(
|
||||
defaultState: S,
|
||||
...actionHandlers: ActionHandler<S, any>[]
|
||||
): any
|
||||
|
||||
interface AppState {
|
||||
dummy: string
|
||||
}
|
||||
|
||||
const defaultState: AppState = {
|
||||
dummy: ''
|
||||
}
|
||||
|
||||
const NON_VOID_ACTION: ActionType<number> = 'NON_VOID_ACTION'
|
||||
, VOID_ACTION: ActionType<void> = '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<P extends keyof R>(x: P, callback: R[P]): void;
|
||||
};
|
||||
|
||||
declare var x: O;
|
||||
x.on('a', a => {});
|
||||
|
||||
// #29775
|
||||
|
||||
namespace N1 {
|
||||
|
||||
declare class Component<P> {
|
||||
constructor(props: P);
|
||||
}
|
||||
|
||||
interface ComponentClass<P = {}> {
|
||||
new (props: P): Component<P>;
|
||||
}
|
||||
|
||||
type CreateElementChildren<P> =
|
||||
P extends { children?: infer C }
|
||||
? C extends any[]
|
||||
? C
|
||||
: C[]
|
||||
: unknown;
|
||||
|
||||
declare function createElement<P extends {}>(
|
||||
type: ComponentClass<P>,
|
||||
...children: CreateElementChildren<P>
|
||||
): any;
|
||||
|
||||
declare function createElement2<P extends {}>(
|
||||
type: ComponentClass<P>,
|
||||
child: CreateElementChildren<P>
|
||||
): any;
|
||||
|
||||
class InferFunctionTypes extends Component<{children: (foo: number) => string}> {}
|
||||
|
||||
createElement(InferFunctionTypes, (foo) => "" + foo);
|
||||
|
||||
createElement2(InferFunctionTypes, [(foo) => "" + foo]);
|
||||
|
||||
}
|
||||
|
||||
// #30341
|
||||
|
||||
type InnerBox<T> = {
|
||||
value: T;
|
||||
}
|
||||
|
||||
type OuterBox<T> = {
|
||||
inner: InnerBox<T>
|
||||
};
|
||||
|
||||
type BoxConsumerFromOuterBox<T> =
|
||||
T extends OuterBox<infer U> ?
|
||||
(box: InnerBox<U>) => void :
|
||||
never;
|
||||
|
||||
declare function passContentsToFunc<T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>): void;
|
||||
|
||||
declare const outerBoxOfString: OuterBox<string>;
|
||||
|
||||
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);
|
||||
409
tests/baselines/reference/instantiateContextualTypes.symbols
Normal file
409
tests/baselines/reference/instantiateContextualTypes.symbols
Normal file
@@ -0,0 +1,409 @@
|
||||
=== tests/cases/compiler/instantiateContextualTypes.ts ===
|
||||
// #6611
|
||||
|
||||
export interface A<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<a>(values: A<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<T> {
|
||||
>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<P> { 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<Props = {}, Values = object>
|
||||
>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<Props & BaseProps<Values>> {
|
||||
>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 extends string | number>(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<P> = 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<S, P> = 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<S, P> {
|
||||
>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<P>
|
||||
>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<S, P>
|
||||
>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<S, P>(actionType: ActionType<P>, handler: Handler<S, P>): ActionHandler<S, P>
|
||||
>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<S>(
|
||||
>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<S, any>[]
|
||||
>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<number> = '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> = '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<P extends keyof R>(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<P> {
|
||||
>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<P = {}> {
|
||||
>ComponentClass : Symbol(ComponentClass, Decl(instantiateContextualTypes.ts, 88, 1))
|
||||
>P : Symbol(P, Decl(instantiateContextualTypes.ts, 90, 25))
|
||||
|
||||
new (props: P): Component<P>;
|
||||
>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<P> =
|
||||
>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<P extends {}>(
|
||||
>createElement : Symbol(createElement, Decl(instantiateContextualTypes.ts, 99, 12))
|
||||
>P : Symbol(P, Decl(instantiateContextualTypes.ts, 101, 31))
|
||||
|
||||
type: ComponentClass<P>,
|
||||
>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<P>
|
||||
>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<P extends {}>(
|
||||
>createElement2 : Symbol(createElement2, Decl(instantiateContextualTypes.ts, 104, 7))
|
||||
>P : Symbol(P, Decl(instantiateContextualTypes.ts, 106, 32))
|
||||
|
||||
type: ComponentClass<P>,
|
||||
>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<P>
|
||||
>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<T> = {
|
||||
>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<T> = {
|
||||
>OuterBox : Symbol(OuterBox, Decl(instantiateContextualTypes.ts, 123, 1))
|
||||
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 125, 14))
|
||||
|
||||
inner: InnerBox<T>
|
||||
>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<T> =
|
||||
>BoxConsumerFromOuterBox : Symbol(BoxConsumerFromOuterBox, Decl(instantiateContextualTypes.ts, 127, 2))
|
||||
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 129, 29))
|
||||
|
||||
T extends OuterBox<infer U> ?
|
||||
>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<U>) => 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<T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>): 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<string>;
|
||||
>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))
|
||||
|
||||
328
tests/baselines/reference/instantiateContextualTypes.types
Normal file
328
tests/baselines/reference/instantiateContextualTypes.types
Normal file
@@ -0,0 +1,328 @@
|
||||
=== tests/cases/compiler/instantiateContextualTypes.ts ===
|
||||
// #6611
|
||||
|
||||
export interface A<a> {
|
||||
value: a;
|
||||
>value : a
|
||||
}
|
||||
|
||||
function fn<a>(values: A<a>, value: a) : void {
|
||||
>fn : <a>(values: A<a>, value: a) => void
|
||||
>values : A<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 : <a>(values: A<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<T> {
|
||||
initialValues: T;
|
||||
>initialValues : T
|
||||
|
||||
nextValues: (cur: T) => T;
|
||||
>nextValues : (cur: T) => T
|
||||
>cur : T
|
||||
}
|
||||
declare class Component<P> { constructor(props: P); props: P; }
|
||||
>Component : Component<P>
|
||||
>props : P
|
||||
>props : P
|
||||
|
||||
declare class GenericComponent<Props = {}, Values = object>
|
||||
>GenericComponent : GenericComponent<Props, Values>
|
||||
|
||||
extends Component<Props & BaseProps<Values>> {
|
||||
>Component : Component<Props & BaseProps<Values>>
|
||||
|
||||
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 extends string | number>(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void;
|
||||
>useStringOrNumber : <T extends string | number>(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 extends string | number>(t: T, useIt: T extends string ? (s: string) => void : (n: number) => void) => void
|
||||
>"" : ""
|
||||
>foo => {} : (foo: string) => void
|
||||
>foo : string
|
||||
|
||||
// #25299
|
||||
|
||||
type ActionType<P> = string & { attachPayloadTypeHack?: P & never }
|
||||
>ActionType : ActionType<P>
|
||||
>attachPayloadTypeHack : undefined
|
||||
|
||||
type Handler<S, P> = P extends void
|
||||
>Handler : Handler<S, P>
|
||||
|
||||
? (state: S) => S
|
||||
>state : S
|
||||
|
||||
: (state: S, payload: P) => S
|
||||
>state : S
|
||||
>payload : P
|
||||
|
||||
interface ActionHandler<S, P> {
|
||||
actionType: ActionType<P>
|
||||
>actionType : ActionType<P>
|
||||
|
||||
handler: Handler<S, P>
|
||||
>handler : Handler<S, P>
|
||||
}
|
||||
|
||||
declare function handler<S, P>(actionType: ActionType<P>, handler: Handler<S, P>): ActionHandler<S, P>
|
||||
>handler : <S, P>(actionType: ActionType<P>, handler: Handler<S, P>) => ActionHandler<S, P>
|
||||
>actionType : ActionType<P>
|
||||
>handler : Handler<S, P>
|
||||
|
||||
declare function createReducer<S>(
|
||||
>createReducer : <S>(defaultState: S, ...actionHandlers: ActionHandler<S, any>[]) => any
|
||||
|
||||
defaultState: S,
|
||||
>defaultState : S
|
||||
|
||||
...actionHandlers: ActionHandler<S, any>[]
|
||||
>actionHandlers : ActionHandler<S, any>[]
|
||||
|
||||
): any
|
||||
|
||||
interface AppState {
|
||||
dummy: string
|
||||
>dummy : string
|
||||
}
|
||||
|
||||
const defaultState: AppState = {
|
||||
>defaultState : AppState
|
||||
>{ dummy: ''} : { dummy: string; }
|
||||
|
||||
dummy: ''
|
||||
>dummy : string
|
||||
>'' : ""
|
||||
}
|
||||
|
||||
const NON_VOID_ACTION: ActionType<number> = 'NON_VOID_ACTION'
|
||||
>NON_VOID_ACTION : ActionType<number>
|
||||
>'NON_VOID_ACTION' : "NON_VOID_ACTION"
|
||||
|
||||
, VOID_ACTION: ActionType<void> = 'VOID_ACTION'
|
||||
>VOID_ACTION : ActionType<void>
|
||||
>'VOID_ACTION' : "VOID_ACTION"
|
||||
|
||||
createReducer(
|
||||
>createReducer( defaultState, handler(NON_VOID_ACTION, (state, _payload) => state), handler(VOID_ACTION, state => state)) : any
|
||||
>createReducer : <S>(defaultState: S, ...actionHandlers: ActionHandler<S, any>[]) => any
|
||||
|
||||
defaultState,
|
||||
>defaultState : AppState
|
||||
|
||||
handler(NON_VOID_ACTION, (state, _payload) => state),
|
||||
>handler(NON_VOID_ACTION, (state, _payload) => state) : ActionHandler<AppState, number>
|
||||
>handler : <S, P>(actionType: ActionType<P>, handler: Handler<S, P>) => ActionHandler<S, P>
|
||||
>NON_VOID_ACTION : ActionType<number>
|
||||
>(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<AppState, void>
|
||||
>handler : <S, P>(actionType: ActionType<P>, handler: Handler<S, P>) => ActionHandler<S, P>
|
||||
>VOID_ACTION : ActionType<void>
|
||||
>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<P extends keyof R>(x: P, callback: R[P]): void;
|
||||
>on : <P extends "a" | "b">(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 : <P extends "a" | "b">(x: P, callback: R[P]) => void
|
||||
>x : O
|
||||
>on : <P extends "a" | "b">(x: P, callback: R[P]) => void
|
||||
>'a' : "a"
|
||||
>a => {} : (a: number) => void
|
||||
>a : number
|
||||
|
||||
// #29775
|
||||
|
||||
namespace N1 {
|
||||
>N1 : typeof N1
|
||||
|
||||
declare class Component<P> {
|
||||
>Component : Component<P>
|
||||
|
||||
constructor(props: P);
|
||||
>props : P
|
||||
}
|
||||
|
||||
interface ComponentClass<P = {}> {
|
||||
new (props: P): Component<P>;
|
||||
>props : P
|
||||
}
|
||||
|
||||
type CreateElementChildren<P> =
|
||||
>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<P extends {}>(
|
||||
>createElement : <P extends {}>(type: ComponentClass<P>, ...children: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any
|
||||
|
||||
type: ComponentClass<P>,
|
||||
>type : ComponentClass<P>
|
||||
|
||||
...children: CreateElementChildren<P>
|
||||
>children : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown
|
||||
|
||||
): any;
|
||||
|
||||
declare function createElement2<P extends {}>(
|
||||
>createElement2 : <P extends {}>(type: ComponentClass<P>, child: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any
|
||||
|
||||
type: ComponentClass<P>,
|
||||
>type : ComponentClass<P>
|
||||
|
||||
child: CreateElementChildren<P>
|
||||
>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 : <P extends {}>(type: ComponentClass<P>, ...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 : <P extends {}>(type: ComponentClass<P>, 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<T> = {
|
||||
>InnerBox : InnerBox<T>
|
||||
|
||||
value: T;
|
||||
>value : T
|
||||
}
|
||||
|
||||
type OuterBox<T> = {
|
||||
>OuterBox : OuterBox<T>
|
||||
|
||||
inner: InnerBox<T>
|
||||
>inner : InnerBox<T>
|
||||
|
||||
};
|
||||
|
||||
type BoxConsumerFromOuterBox<T> =
|
||||
>BoxConsumerFromOuterBox : BoxConsumerFromOuterBox<T>
|
||||
|
||||
T extends OuterBox<infer U> ?
|
||||
(box: InnerBox<U>) => void :
|
||||
>box : InnerBox<U>
|
||||
|
||||
never;
|
||||
|
||||
declare function passContentsToFunc<T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>): void;
|
||||
>passContentsToFunc : <T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>) => void
|
||||
>outerBox : T
|
||||
>consumer : BoxConsumerFromOuterBox<T>
|
||||
|
||||
declare const outerBoxOfString: OuterBox<string>;
|
||||
>outerBoxOfString : OuterBox<string>
|
||||
|
||||
passContentsToFunc(outerBoxOfString, box => box.value);
|
||||
>passContentsToFunc(outerBoxOfString, box => box.value) : void
|
||||
>passContentsToFunc : <T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>) => void
|
||||
>outerBoxOfString : OuterBox<string>
|
||||
>box => box.value : (box: InnerBox<string>) => string
|
||||
>box : InnerBox<string>
|
||||
>box.value : string
|
||||
>box : InnerBox<string>
|
||||
>value : string
|
||||
|
||||
142
tests/cases/compiler/instantiateContextualTypes.ts
Normal file
142
tests/cases/compiler/instantiateContextualTypes.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
// @strict: true
|
||||
// @target: es6
|
||||
|
||||
// #6611
|
||||
|
||||
export interface A<a> {
|
||||
value: a;
|
||||
}
|
||||
|
||||
function fn<a>(values: A<a>, value: a) : void {
|
||||
}
|
||||
|
||||
declare let handlers: A<(value: number) => void>;
|
||||
fn(handlers, value => alert(value));
|
||||
|
||||
// #21382
|
||||
|
||||
interface BaseProps<T> {
|
||||
initialValues: T;
|
||||
nextValues: (cur: T) => T;
|
||||
}
|
||||
declare class Component<P> { constructor(props: P); props: P; }
|
||||
declare class GenericComponent<Props = {}, Values = object>
|
||||
extends Component<Props & BaseProps<Values>> {
|
||||
iv: Values;
|
||||
}
|
||||
|
||||
new GenericComponent({ initialValues: 12, nextValues: val => 12 });
|
||||
|
||||
// #22149
|
||||
|
||||
declare function useStringOrNumber<T extends string | number>(t: T, useIt: T extends string ? ((s: string) => void) : ((n: number) => void)): void;
|
||||
useStringOrNumber("", foo => {});
|
||||
|
||||
// #25299
|
||||
|
||||
type ActionType<P> = string & { attachPayloadTypeHack?: P & never }
|
||||
|
||||
type Handler<S, P> = P extends void
|
||||
? (state: S) => S
|
||||
: (state: S, payload: P) => S
|
||||
|
||||
interface ActionHandler<S, P> {
|
||||
actionType: ActionType<P>
|
||||
handler: Handler<S, P>
|
||||
}
|
||||
|
||||
declare function handler<S, P>(actionType: ActionType<P>, handler: Handler<S, P>): ActionHandler<S, P>
|
||||
|
||||
declare function createReducer<S>(
|
||||
defaultState: S,
|
||||
...actionHandlers: ActionHandler<S, any>[]
|
||||
): any
|
||||
|
||||
interface AppState {
|
||||
dummy: string
|
||||
}
|
||||
|
||||
const defaultState: AppState = {
|
||||
dummy: ''
|
||||
}
|
||||
|
||||
const NON_VOID_ACTION: ActionType<number> = 'NON_VOID_ACTION'
|
||||
, VOID_ACTION: ActionType<void> = '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<P extends keyof R>(x: P, callback: R[P]): void;
|
||||
};
|
||||
|
||||
declare var x: O;
|
||||
x.on('a', a => {});
|
||||
|
||||
// #29775
|
||||
|
||||
namespace N1 {
|
||||
|
||||
declare class Component<P> {
|
||||
constructor(props: P);
|
||||
}
|
||||
|
||||
interface ComponentClass<P = {}> {
|
||||
new (props: P): Component<P>;
|
||||
}
|
||||
|
||||
type CreateElementChildren<P> =
|
||||
P extends { children?: infer C }
|
||||
? C extends any[]
|
||||
? C
|
||||
: C[]
|
||||
: unknown;
|
||||
|
||||
declare function createElement<P extends {}>(
|
||||
type: ComponentClass<P>,
|
||||
...children: CreateElementChildren<P>
|
||||
): any;
|
||||
|
||||
declare function createElement2<P extends {}>(
|
||||
type: ComponentClass<P>,
|
||||
child: CreateElementChildren<P>
|
||||
): any;
|
||||
|
||||
class InferFunctionTypes extends Component<{children: (foo: number) => string}> {}
|
||||
|
||||
createElement(InferFunctionTypes, (foo) => "" + foo);
|
||||
|
||||
createElement2(InferFunctionTypes, [(foo) => "" + foo]);
|
||||
|
||||
}
|
||||
|
||||
// #30341
|
||||
|
||||
type InnerBox<T> = {
|
||||
value: T;
|
||||
}
|
||||
|
||||
type OuterBox<T> = {
|
||||
inner: InnerBox<T>
|
||||
};
|
||||
|
||||
type BoxConsumerFromOuterBox<T> =
|
||||
T extends OuterBox<infer U> ?
|
||||
(box: InnerBox<U>) => void :
|
||||
never;
|
||||
|
||||
declare function passContentsToFunc<T>(outerBox: T, consumer: BoxConsumerFromOuterBox<T>): void;
|
||||
|
||||
declare const outerBoxOfString: OuterBox<string>;
|
||||
|
||||
passContentsToFunc(outerBoxOfString, box => box.value);
|
||||
Reference in New Issue
Block a user