Merge pull request #30568 from Microsoft/instantiateContextualTypes

Contextual typing based on instantiated types
This commit is contained in:
Anders Hejlsberg
2019-03-28 12:38:01 -07:00
committed by GitHub
8 changed files with 1102 additions and 53 deletions

View File

@@ -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 ?

View File

@@ -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

View File

@@ -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

View File

@@ -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>() {

View 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);

View 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))

View 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

View 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);