Merge pull request #30215 from Microsoft/higherOrderFunctionTypeInference

Higher order function type inference
This commit is contained in:
Anders Hejlsberg
2019-03-08 10:41:32 -08:00
committed by GitHub
13 changed files with 2555 additions and 126 deletions

View File

@@ -228,9 +228,9 @@ namespace ts {
isContextSensitive,
getFullyQualifiedName,
getResolvedSignature: (node, candidatesOutArray, agumentCount) =>
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ false),
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.Normal),
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) =>
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ true),
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp),
getConstantValue: nodeIn => {
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
return node ? getConstantValue(node) : undefined;
@@ -374,10 +374,10 @@ namespace ts {
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
};
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, isForSignatureHelp: boolean): Signature | undefined {
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
const node = getParseTreeNode(nodeIn, isCallLikeExpression);
apparentArgumentCount = argumentCount;
const res = node ? getResolvedSignature(node, candidatesOutArray, isForSignatureHelp) : undefined;
const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
apparentArgumentCount = undefined;
return res;
}
@@ -688,10 +688,12 @@ namespace ts {
}
const enum CheckMode {
Normal = 0, // Normal type checking
SkipContextSensitive = 1, // Skip context sensitive function expressions
Inferential = 2, // Inferential typing
Contextual = 3, // Normal type checking informed by a contextual type, therefore not cacheable
Normal = 0, // Normal type checking
Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
Inferential = 1 << 1, // Inferential typing
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
}
const enum CallbackCheck {
@@ -3981,7 +3983,7 @@ namespace ts {
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic
const shouldUseGeneratedName =
context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
type.symbol.declarations[0] &&
type.symbol.declarations && type.symbol.declarations[0] &&
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
typeParameterShadowsNameInScope(type, context);
const name = shouldUseGeneratedName
@@ -8373,9 +8375,23 @@ namespace ts {
return undefined;
}
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature {
return getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
if (inferredTypeParameters) {
const returnSignature = getSingleCallSignature(getReturnTypeOfSignature(instantiatedSignature));
if (returnSignature) {
const newReturnSignature = cloneSignature(returnSignature);
newReturnSignature.typeParameters = inferredTypeParameters;
newReturnSignature.target = returnSignature.target;
newReturnSignature.mapper = returnSignature.mapper;
const newInstantiatedSignature = cloneSignature(instantiatedSignature);
newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
return newInstantiatedSignature;
}
}
return instantiatedSignature;
}
function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
const instantiations = signature.instantiations || (signature.instantiations = createMap<Signature>());
const id = getTypeListId(typeArguments);
@@ -8389,6 +8405,7 @@ namespace ts {
function createSignatureInstantiation(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
}
function createSignatureTypeMapper(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): TypeMapper {
return createTypeMapper(signature.typeParameters!, typeArguments);
}
@@ -20035,7 +20052,12 @@ namespace ts {
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes);
const sourceSignature = contextualMapper ? instantiateSignature(contextualSignature, contextualMapper) : contextualSignature;
// We clone the contextualMapper to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
// the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
// for T but leave it possible to later infer '[any]' back to A.
const restType = getEffectiveRestType(contextualSignature);
const mapper = contextualMapper && restType && restType.flags & TypeFlags.TypeParameter ? cloneTypeMapper(contextualMapper) : contextualMapper;
const sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
forEachMatchingParameterType(sourceSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypes(context.inferences, source, target);
@@ -20052,16 +20074,14 @@ namespace ts {
return getSignatureInstantiation(signature, getInferredTypes(context), isInJSFile(contextualSignature.declaration));
}
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, checkMode: CheckMode, context: InferenceContext): Type[] {
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] !== undefined ? identityMapper : context);
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
inferTypes(context.inferences, checkAttrType, paramType);
return getInferredTypes(context);
}
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, checkMode: CheckMode, context: InferenceContext): Type[] {
// Clear out all the inference results from the last time inferTypeArguments was called on this context
for (const inference of context.inferences) {
// As an optimization, we don't have to clear (and later recompute) inferred types
@@ -20074,7 +20094,7 @@ namespace ts {
}
if (isJsxOpeningLikeElement(node)) {
return inferJsxTypeArguments(node, signature, excludeArgument, context);
return inferJsxTypeArguments(node, signature, checkMode, context);
}
// If a contextual type is available, infer from that type to the return type of the call expression. For
@@ -20121,10 +20141,7 @@ namespace ts {
const arg = args[i];
if (arg.kind !== SyntaxKind.OmittedExpression) {
const paramType = getTypeAtPosition(signature, i);
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
// context sensitive function expressions as wildcards
const mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
const argType = checkExpressionWithContextualType(arg, paramType, mapper);
const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
inferTypes(context.inferences, argType, paramType);
}
}
@@ -20152,7 +20169,7 @@ namespace ts {
// and the argument are ...x forms.
return arg.kind === SyntaxKind.SyntheticExpression ?
createArrayType((<SyntheticExpression>arg).type) :
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context));
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context, CheckMode.Normal));
}
}
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
@@ -20160,7 +20177,7 @@ namespace ts {
const types = [];
let spreadIndex = -1;
for (let i = index; i < argCount; i++) {
const argType = checkExpressionWithContextualType(args[i], contextualType, context);
const argType = checkExpressionWithContextualType(args[i], contextualType, context, CheckMode.Normal);
if (spreadIndex < 0 && isSpreadArgument(args[i])) {
spreadIndex = i - index;
}
@@ -20218,14 +20235,13 @@ namespace ts {
* @param node a JSX opening-like element we are trying to figure its call signature
* @param signature a candidate signature we are trying whether it is a call signature
* @param relation a relationship to check parameter and argument type
* @param excludeArgument
*/
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[] | undefined, reportErrors: boolean) {
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, checkMode: CheckMode, reportErrors: boolean) {
// Stateless function components can have maximum of three arguments: "props", "context", and "updater".
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
// can be specified by users through attributes property.
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] ? identityMapper : undefined);
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined, checkMode);
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
}
@@ -20234,10 +20250,10 @@ namespace ts {
args: ReadonlyArray<Expression>,
signature: Signature,
relation: Map<RelationComparisonResult>,
excludeArgument: boolean[] | undefined,
checkMode: CheckMode,
reportErrors: boolean) {
if (isJsxOpeningLikeElement(node)) {
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, excludeArgument, reportErrors);
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors);
}
const thisType = getThisTypeOfSignature(signature);
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
@@ -20259,11 +20275,11 @@ namespace ts {
const arg = args[i];
if (arg.kind !== SyntaxKind.OmittedExpression) {
const paramType = getTypeAtPosition(signature, i);
const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
// If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
const argType = checkExpressionWithContextualType(arg, paramType, /*contextualMapper*/ undefined, checkMode);
// If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
// we obtain the regular type of any object literal arguments because we may not have inferred complete
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) {
return false;
}
@@ -20479,7 +20495,7 @@ namespace ts {
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
}
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean, fallbackError?: DiagnosticMessage): Signature {
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, fallbackError?: DiagnosticMessage): Signature {
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
const isDecorator = node.kind === SyntaxKind.Decorator;
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
@@ -20521,7 +20537,7 @@ namespace ts {
// For a decorator, no arguments are susceptible to contextual typing due to the fact
// decorators are applied to a declaration by the emitter, and not to an expression.
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
let excludeArgument = !isDecorator && !isSingleNonGenericCandidate ? getExcludeArgument(args) : undefined;
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
// The following variables are captured and modified by calls to chooseOverload.
// If overload resolution or type argument inference fails, we want to report the
@@ -20552,7 +20568,7 @@ namespace ts {
// If we are in signature help, a trailing comma indicates that we intend to provide another argument,
// so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
const signatureHelpTrailingComma =
isForSignatureHelp && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
!!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
// Section 4.12.1:
// if the candidate list contains one or more signatures for which the type of each argument
@@ -20580,12 +20596,7 @@ namespace ts {
// skip the checkApplicableSignature check.
if (reportErrors) {
if (candidateForArgumentError) {
// excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
// The importance of excludeArgument is to prevent us from typing function expression parameters
// in arguments too early. If possible, we'd like to only type them once we know the correct
// overload. However, this matters for the case where the call is correct. When the call is
// an error, we don't need to exclude any arguments, although it would cause no harm to do so.
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, CheckMode.Normal, /*reportErrors*/ true);
}
else if (candidateForArgumentArityError) {
diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
@@ -20619,7 +20630,7 @@ namespace ts {
if (typeArguments || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
return undefined;
}
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false)) {
candidateForArgumentError = candidate;
return undefined;
}
@@ -20646,9 +20657,10 @@ namespace ts {
}
else {
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
}
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
// If the original signature has a generic rest type, instantiation may produce a
// signature with different arity and we need to perform another arity check.
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
@@ -20659,21 +20671,21 @@ namespace ts {
else {
checkCandidate = candidate;
}
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
// Give preference to error candidates that have no rest parameters (as they are more specific)
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
candidateForArgumentError = checkCandidate;
}
continue;
}
if (excludeArgument) {
if (argCheckMode) {
// If one or more context sensitive arguments were excluded, we start including
// them now (and keeping do so for any subsequent candidates) and perform a second
// round of type inference and applicability checking for this particular candidate.
excludeArgument = undefined;
argCheckMode = CheckMode.Normal;
if (inferenceContext) {
const typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
// If the original signature has a generic rest type, instantiation may produce a
// signature with different arity and we need to perform another arity check.
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
@@ -20681,7 +20693,7 @@ namespace ts {
continue;
}
}
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
// Give preference to error candidates that have no rest parameters (as they are more specific)
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
candidateForArgumentError = checkCandidate;
@@ -20697,21 +20709,6 @@ namespace ts {
}
}
function getExcludeArgument(args: ReadonlyArray<Expression>): boolean[] | undefined {
let excludeArgument: boolean[] | undefined;
// We do not need to call `getEffectiveArgumentCount` here as it only
// applies when calculating the number of arguments for a decorator.
for (let i = 0; i < args.length; i++) {
if (isContextSensitive(args[i])) {
if (!excludeArgument) {
excludeArgument = new Array(args.length);
}
excludeArgument[i] = true;
}
}
return excludeArgument;
}
// No signature was applicable. We have already reported the errors for the invalid signature.
// If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
function getCandidateForOverloadFailure(
@@ -20811,7 +20808,7 @@ namespace ts {
function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: ReadonlyArray<TypeParameter>, candidate: Signature, args: ReadonlyArray<Expression>): Signature {
const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
const typeArgumentTypes = inferTypeArguments(node, candidate, args, getExcludeArgument(args), inferenceContext);
const typeArgumentTypes = inferTypeArguments(node, candidate, args, CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
return createSignatureInstantiation(candidate, typeArgumentTypes);
}
@@ -20834,7 +20831,7 @@ namespace ts {
return maxParamsIndex;
}
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
const superType = checkSuperExpression(node.expression);
if (isTypeAny(superType)) {
@@ -20849,7 +20846,7 @@ namespace ts {
const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!);
if (baseTypeNode) {
const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
return resolveCall(node, baseConstructors, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, baseConstructors, candidatesOutArray, checkMode);
}
}
return resolveUntypedCall(node);
@@ -20909,12 +20906,32 @@ namespace ts {
}
return resolveErrorCall(node);
}
// When a call to a generic function is an argument to an outer call to a generic function for which
// inference is in process, we have a choice to make. If the inner call relies on inferences made from
// its contextual type to its return type, deferring the inner call processing allows the best possible
// contextual type to accumulate. But if the outer call relies on inferences made from the return type of
// the inner call, the inner call should be processed early. There's no sure way to know which choice is
// right (only a full unification algorithm can determine that), so we resort to the following heuristic:
// If no type arguments are specified in the inner call and at least one call signature is generic and
// returns a function type, we choose to defer processing. This narrowly permits function composition
// operators to flow inferences through return types, but otherwise processes calls right away. We
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
// from which we never make inferences).
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
skippedGenericFunction(node, checkMode);
return resolvingSignature;
}
// If the function is explicitly marked with `@class`, then it must be constructed.
if (callSignatures.some(sig => isInJSFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) {
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
}
function isGenericFunctionReturningFunction(signature: Signature) {
return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
}
/**
@@ -20928,7 +20945,7 @@ namespace ts {
!numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
}
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (node.arguments && languageVersion < ScriptTarget.ES5) {
const spreadIndex = getSpreadArgumentIndex(node.arguments);
if (spreadIndex >= 0) {
@@ -20981,7 +20998,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, constructSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, constructSignatures, candidatesOutArray, checkMode);
}
// If expressionType's apparent type is an object type with no construct signatures but
@@ -20990,7 +21007,7 @@ namespace ts {
// operation is Any. It is an error to have a Void this type.
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
if (callSignatures.length) {
const signature = resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode);
if (!noImplicitAny) {
if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
@@ -21100,7 +21117,7 @@ namespace ts {
}
}
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
const tagType = checkExpression(node.tag);
const apparentType = getApparentType(tagType);
@@ -21121,7 +21138,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
}
/**
@@ -21152,7 +21169,7 @@ namespace ts {
/**
* Resolves a decorator as if it were a call expression.
*/
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
const funcType = checkExpression(node.expression);
const apparentType = getApparentType(funcType);
if (apparentType === errorType) {
@@ -21181,7 +21198,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp, headMessage);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, headMessage);
}
function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature {
@@ -21210,11 +21227,11 @@ namespace ts {
);
}
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (isJsxIntrinsicIdentifier(node.tagName)) {
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
const fakeSignature = createSignatureForJSXIntrinsic(node, result);
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined), result, node.tagName, node.attributes);
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes);
return fakeSignature;
}
const exprTypes = checkExpression(node.tagName);
@@ -21234,7 +21251,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, signatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, signatures, candidatesOutArray, checkMode);
}
/**
@@ -21249,19 +21266,19 @@ namespace ts {
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
}
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
switch (node.kind) {
case SyntaxKind.CallExpression:
return resolveCallExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveCallExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.NewExpression:
return resolveNewExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveNewExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.TaggedTemplateExpression:
return resolveTaggedTemplateExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.Decorator:
return resolveDecorator(node, candidatesOutArray, isForSignatureHelp);
return resolveDecorator(node, candidatesOutArray, checkMode);
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxSelfClosingElement:
return resolveJsxOpeningLikeElement(node, candidatesOutArray, isForSignatureHelp);
return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
}
throw Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
}
@@ -21273,7 +21290,7 @@ namespace ts {
* the function will fill it up with appropriate candidate signatures
* @return a signature of the call-like expression or undefined if one can't be found
*/
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, isForSignatureHelp = false): Signature {
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, checkMode?: CheckMode): Signature {
const links = getNodeLinks(node);
// If getResolvedSignature has already been called, we will have cached the resolvedSignature.
// However, it is possible that either candidatesOutArray was not passed in the first time,
@@ -21284,11 +21301,15 @@ namespace ts {
return cached;
}
links.resolvedSignature = resolvingSignature;
const result = resolveSignature(node, candidatesOutArray, isForSignatureHelp);
// If signature resolution originated in control flow type analysis (for example to compute the
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
// types from the control flow analysis.
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
const result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
// When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
// resolution should be deferred.
if (result !== resolvingSignature) {
// If signature resolution originated in control flow type analysis (for example to compute the
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
// types from the control flow analysis.
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
}
return result;
}
@@ -21372,10 +21393,15 @@ namespace ts {
* @param node The call/new expression to be checked.
* @returns On success, the expression's signature's return type. On failure, anyType.
*/
function checkCallExpression(node: CallExpression | NewExpression): Type {
function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments);
const signature = getResolvedSignature(node);
const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
if (signature === resolvingSignature) {
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
// returns a function type. We defer checking and return anyFunctionType.
return silentNeverType;
}
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return voidType;
@@ -21876,7 +21902,7 @@ namespace ts {
const functionFlags = getFunctionFlags(func);
let type: Type;
if (func.body.kind !== SyntaxKind.Block) {
type = checkExpressionCached(func.body, checkMode);
type = checkExpressionCached(func.body, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
if (functionFlags & FunctionFlags.Async) {
// From within an async function you can return either a non-promise value or a promise. Any
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -22066,7 +22092,7 @@ namespace ts {
forEachReturnStatement(<Block>func.body, returnStatement => {
const expr = returnStatement.expression;
if (expr) {
let type = checkExpressionCached(expr, checkMode);
let type = checkExpressionCached(expr, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
if (functionFlags & FunctionFlags.Async) {
// From within an async function you can return either a non-promise value or a promise. Any
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -22166,7 +22192,7 @@ namespace ts {
checkNodeDeferred(node);
// The identityMapper object is used to indicate that function expressions are wildcards
if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) {
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
if (!getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
const links = getNodeLinks(node);
@@ -22206,7 +22232,7 @@ namespace ts {
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
if (isContextSensitive(node)) {
const contextualMapper = getContextualMapper(node);
if (checkMode === CheckMode.Inferential) {
if (checkMode && checkMode & CheckMode.Inferential) {
inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
}
const instantiatedContextualSignature = contextualMapper === identityMapper ?
@@ -23217,15 +23243,13 @@ namespace ts {
return node;
}
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined): Type {
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined, checkMode: CheckMode): Type {
const context = getContextNode(node);
const saveContextualType = context.contextualType;
const saveContextualMapper = context.contextualMapper;
context.contextualType = contextualType;
context.contextualMapper = contextualMapper;
const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive :
contextualMapper ? CheckMode.Inferential : CheckMode.Contextual;
const type = checkExpression(node, checkMode);
const type = checkExpression(node, checkMode | CheckMode.Contextual | (contextualMapper ? CheckMode.Inferential : 0));
// We strip literal freshness when an appropriate contextual type is present such that contextually typed
// literals always preserve their literal types (otherwise they might widen during type inference). An alternative
// here would be to not mark contextually typed literals as fresh in the first place.
@@ -23239,7 +23263,7 @@ namespace ts {
function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
if (checkMode) {
if (checkMode && checkMode !== CheckMode.Normal) {
return checkExpression(node, checkMode);
}
// When computing a type that we're going to cache, we need to ignore any ongoing control flow
@@ -23347,22 +23371,127 @@ namespace ts {
}
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
if (checkMode === CheckMode.Inferential) {
if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
const signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
if (checkMode & CheckMode.SkipGenericFunctions) {
skippedGenericFunction(node, checkMode);
return anyFunctionType;
}
const contextualType = getApparentTypeOfContextualType(<Expression>node);
if (contextualType) {
const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
if (contextualSignature && !contextualSignature.typeParameters) {
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
const context = <InferenceContext>getContextualMapper(node);
// We have an expression that is an argument of a generic function for which we are performing
// type argument inference. The expression is of a function type with a single generic call
// signature and a contextual function type with a single non-generic call signature. Now check
// if the outer function returns a function type with a single non-generic call signature and
// if some of the outer function type parameters have no inferences so far. If so, we can
// potentially add inferred type parameters to the outer function return type.
const returnSignature = context.signature && getSingleCallSignature(getReturnTypeOfSignature(context.signature));
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
// Instantiate the expression type with its own type parameters as type arguments. This
// ensures that the type parameters are not erased to type any during type inference such
// that they can be inferred as actual types.
const uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
const strippedType = getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters));
// Infer from the stripped expression type to the contextual type starting with an empty
// set of inference candidates.
const inferences = map(context.typeParameters, createInferenceInfo);
inferTypes(inferences, strippedType, contextualType);
// If we produced some inference candidates and if the type parameters for which we produced
// candidates do not already have existing inferences, we adopt the new inference candidates and
// add the type parameters of the expression type to the set of inferred type parameters for
// the outer function return type.
if (some(inferences, hasInferenceCandidates) && !hasOverlappingInferences(context.inferences, inferences)) {
mergeInferences(context.inferences, inferences);
context.inferredTypeParameters = concatenate(context.inferredTypeParameters, uniqueTypeParameters);
return strippedType;
}
}
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
}
}
}
}
return type;
}
function skippedGenericFunction(node: Node, checkMode: CheckMode) {
if (checkMode & CheckMode.Inferential) {
// We have skipped a generic function during inferential typing. Obtain the inference context and
// indicate this has occurred such that we know a second pass of inference is be needed.
const context = <InferenceContext>getContextualMapper(node);
context.flags |= InferenceFlags.SkippedGenericFunction;
}
}
function hasInferenceCandidates(info: InferenceInfo) {
return !!(info.candidates || info.contraCandidates);
}
function hasOverlappingInferences(a: InferenceInfo[], b: InferenceInfo[]) {
for (let i = 0; i < a.length; i++) {
if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
return true;
}
}
return false;
}
function mergeInferences(target: InferenceInfo[], source: InferenceInfo[]) {
for (let i = 0; i < target.length; i++) {
if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
target[i] = source[i];
}
}
}
function getUniqueTypeParameters(context: InferenceContext, typeParameters: ReadonlyArray<TypeParameter>): ReadonlyArray<TypeParameter> {
const result: TypeParameter[] = [];
let oldTypeParameters: TypeParameter[] | undefined;
let newTypeParameters: TypeParameter[] | undefined;
for (const tp of typeParameters) {
const name = tp.symbol.escapedName;
if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
const newName = getUniqueTypeParameterName(concatenate(context.inferredTypeParameters, result), name);
const symbol = createSymbol(SymbolFlags.TypeParameter, newName);
const newTypeParameter = createTypeParameter(symbol);
newTypeParameter.target = tp;
oldTypeParameters = append(oldTypeParameters, tp);
newTypeParameters = append(newTypeParameters, newTypeParameter);
result.push(newTypeParameter);
}
else {
result.push(tp);
}
}
if (newTypeParameters) {
const mapper = createTypeMapper(oldTypeParameters!, newTypeParameters);
for (const tp of newTypeParameters) {
tp.mapper = mapper;
}
}
return result;
}
function hasTypeParameterByName(typeParameters: ReadonlyArray<TypeParameter> | undefined, name: __String) {
return some(typeParameters, tp => tp.symbol.escapedName === name);
}
function getUniqueTypeParameterName(typeParameters: ReadonlyArray<TypeParameter>, baseName: __String) {
let len = (<string>baseName).length;
while (len > 1 && (<string>baseName).charCodeAt(len - 1) >= CharacterCodes._0 && (<string>baseName).charCodeAt(len - 1) <= CharacterCodes._9) len--;
const s = (<string>baseName).slice(0, len);
for (let index = 1; true; index++) {
const augmentedName = <__String>(s + index);
if (!hasTypeParameterByName(typeParameters, augmentedName)) {
return augmentedName;
}
}
}
/**
* Returns the type of an expression. Unlike checkExpression, this function is simply concerned
* with computing the type and may not fully check all contained sub-expressions for errors.
@@ -23502,7 +23631,7 @@ namespace ts {
}
/* falls through */
case SyntaxKind.NewExpression:
return checkCallExpression(<CallExpression>node);
return checkCallExpression(<CallExpression>node, checkMode);
case SyntaxKind.TaggedTemplateExpression:
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.ParenthesizedExpression:

View File

@@ -4362,6 +4362,7 @@ namespace ts {
NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType)
NoFixing = 1 << 2, // Disable type parameter fixing
SkippedGenericFunction = 1 << 3,
}
/**
@@ -4391,6 +4392,7 @@ namespace ts {
flags: InferenceFlags; // Inference flags
compareTypes: TypeComparer; // Type comparer function
returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any)
inferredTypeParameters?: ReadonlyArray<TypeParameter>;
}
/* @internal */

View File

@@ -1798,7 +1798,7 @@ namespace ts {
const span = createTextSpanFromBounds(start, end);
const formatContext = formatting.getFormatContext(formatOptions);
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
return flatMap(deduplicate<number>(errorCodes, equateValues, compareValues), errorCode => {
cancellationToken.throwIfCancellationRequested();
return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences });
});

View File

@@ -15,8 +15,8 @@ var e = <K>(x: string, y?: K) => x.length;
>length : number
var r99 = map(e); // should be {}[] for S since a generic lambda is not inferentially typed
>r99 : (a: {}[]) => number[]
>map(e) : (a: {}[]) => number[]
>r99 : <K>(a: string[]) => number[]
>map(e) : <K>(a: string[]) => number[]
>map : <S, T>(f: (x: S) => T) => (a: S[]) => T[]
>e : <K>(x: string, y?: K) => number
@@ -37,8 +37,8 @@ var e2 = <K>(x: string, y?: K) => x.length;
>length : number
var r100 = map2(e2); // type arg inference should fail for S since a generic lambda is not inferentially typed. Falls back to { length: number }
>r100 : (a: { length: number; }[]) => number[]
>map2(e2) : (a: { length: number; }[]) => number[]
>r100 : <K>(a: string[]) => number[]
>map2(e2) : <K>(a: string[]) => number[]
>map2 : <S extends { length: number; }, T>(f: (x: S) => T) => (a: S[]) => T[]
>e2 : <K>(x: string, y?: K) => number

View File

@@ -31,8 +31,8 @@ var id: <T>(x:T) => T;
>x : T
var r23 = dot(id)(id);
>r23 : (_: {}) => {}
>dot(id)(id) : (_: {}) => {}
>r23 : <T>(_: T) => {}
>dot(id)(id) : <T>(_: T) => {}
>dot(id) : <U>(g: (_: U) => {}) => (_: U) => {}
>dot : <T, S>(f: (_: T) => S) => <U>(g: (_: U) => T) => (_: U) => S
>id : <T>(x: T) => T

View File

@@ -0,0 +1,193 @@
tests/cases/compiler/genericFunctionInference1.ts(83,14): error TS2345: Argument of type '<a>(value: { key: a; }) => a' is not assignable to parameter of type '(value: Data) => string'.
Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/genericFunctionInference1.ts (1 errors) ====
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
declare function list<T>(a: T): T[];
declare function box<V>(x: V): { value: V };
declare function foo<T extends { value: T }>(x: T): T;
const f00 = pipe(list);
const f01 = pipe(list, box);
const f02 = pipe(box, list);
const f03 = pipe(x => list(x), box);
const f04 = pipe(list, x => box(x));
const f05 = pipe(x => list(x), x => box(x))
const f06 = pipe(list, pipe(box));
const f07 = pipe(x => list(x), pipe(box));
const f08 = pipe(x => list(x), pipe(x => box(x)));
const f09 = pipe(list, x => x.length);
const f10 = pipe(foo);
const f11 = pipe(foo, foo);
const g00: <T>(x: T) => T[] = pipe(list);
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
const g09: <T>(x: T) => number = pipe(list, x => x.length);
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
const f20 = pipe2(list, box);
const f21 = pipe2(box, list);
const f22 = pipe2(list, list);
const f23 = pipe2(box, box);
const f24 = pipe2(f20, f20);
const f25 = pipe2(foo, foo);
const f26 = pipe2(f25, f25);
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
const f30 = pipe3(list, box);
const f31 = pipe3(box, list);
const f32 = pipe3(list, list);
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
const f40 = pipe4([list, box]);
const f41 = pipe4([box, list]);
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
const f50 = pipe5(list); // No higher order inference
// #417
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
var identityM = mirror(identity);
var x = 1;
var y = identity(x);
var z = identityM(x);
// #3038
export function keyOf<a>(value: { key: a; }): a {
return value.key;
}
export interface Data {
key: number;
value: Date;
}
var data: Data[] = [];
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
toKeys(data, keyOf); // Error
~~~~~
!!! error TS2345: Argument of type '<a>(value: { key: a; }) => a' is not assignable to parameter of type '(value: Data) => string'.
!!! error TS2345: Type 'number' is not assignable to type 'string'.
// #9366
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
return (b: b, a: a) => f(a, b);
}
function zip<T, U>(x: T, y: U): [T, U] {
return [x, y];
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
var actual = flip(zip);
// #9366
const map = <T, U>(transform: (t: T) => U) =>
(arr: T[]) => arr.map(transform)
const identityStr = (t: string) => t;
const arr: string[] = map(identityStr)(['a']);
const arr1: string[] = map(identity)(['a']);
// #9949
function of2<a, b>(one: a, two: b): [a, b] {
return [one, two];
}
const flipped = flip(of2);
// #29904.1
type Component<P> = (props: P) => {};
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
declare const MyComponent1: Component<{ foo: 1 }>;
const enhance = pipe(
myHoc1,
myHoc2,
);
const MyComponent2 = enhance(MyComponent1);
// #29904.2
const fn20 = pipe((_a?: {}) => 1);
// #29904.3
type Fn = (n: number) => number;
const fn30: Fn = pipe(
x => x + 1,
x => x * 2,
);
const promise = Promise.resolve(1);
promise.then(
pipe(
x => x + 1,
x => x * 2,
),
);
// #29904.4
declare const getString: () => string;
declare const orUndefined: (name: string) => string | undefined;
declare const identity: <T>(value: T) => T;
const fn40 = pipe(
getString,
string => orUndefined(string),
identity,
);
// #29904.6
declare const getArray: () => string[];
declare const first: <T>(ts: T[]) => T;
const fn60 = pipe(
getArray,
x => x,
first,
);
const fn61 = pipe(
getArray,
identity,
first,
);
const fn62 = pipe(
getArray,
x => x,
x => first(x),
);

View File

@@ -0,0 +1,267 @@
//// [genericFunctionInference1.ts]
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
declare function list<T>(a: T): T[];
declare function box<V>(x: V): { value: V };
declare function foo<T extends { value: T }>(x: T): T;
const f00 = pipe(list);
const f01 = pipe(list, box);
const f02 = pipe(box, list);
const f03 = pipe(x => list(x), box);
const f04 = pipe(list, x => box(x));
const f05 = pipe(x => list(x), x => box(x))
const f06 = pipe(list, pipe(box));
const f07 = pipe(x => list(x), pipe(box));
const f08 = pipe(x => list(x), pipe(x => box(x)));
const f09 = pipe(list, x => x.length);
const f10 = pipe(foo);
const f11 = pipe(foo, foo);
const g00: <T>(x: T) => T[] = pipe(list);
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
const g09: <T>(x: T) => number = pipe(list, x => x.length);
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
const f20 = pipe2(list, box);
const f21 = pipe2(box, list);
const f22 = pipe2(list, list);
const f23 = pipe2(box, box);
const f24 = pipe2(f20, f20);
const f25 = pipe2(foo, foo);
const f26 = pipe2(f25, f25);
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
const f30 = pipe3(list, box);
const f31 = pipe3(box, list);
const f32 = pipe3(list, list);
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
const f40 = pipe4([list, box]);
const f41 = pipe4([box, list]);
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
const f50 = pipe5(list); // No higher order inference
// #417
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
var identityM = mirror(identity);
var x = 1;
var y = identity(x);
var z = identityM(x);
// #3038
export function keyOf<a>(value: { key: a; }): a {
return value.key;
}
export interface Data {
key: number;
value: Date;
}
var data: Data[] = [];
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
toKeys(data, keyOf); // Error
// #9366
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
return (b: b, a: a) => f(a, b);
}
function zip<T, U>(x: T, y: U): [T, U] {
return [x, y];
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
var actual = flip(zip);
// #9366
const map = <T, U>(transform: (t: T) => U) =>
(arr: T[]) => arr.map(transform)
const identityStr = (t: string) => t;
const arr: string[] = map(identityStr)(['a']);
const arr1: string[] = map(identity)(['a']);
// #9949
function of2<a, b>(one: a, two: b): [a, b] {
return [one, two];
}
const flipped = flip(of2);
// #29904.1
type Component<P> = (props: P) => {};
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
declare const MyComponent1: Component<{ foo: 1 }>;
const enhance = pipe(
myHoc1,
myHoc2,
);
const MyComponent2 = enhance(MyComponent1);
// #29904.2
const fn20 = pipe((_a?: {}) => 1);
// #29904.3
type Fn = (n: number) => number;
const fn30: Fn = pipe(
x => x + 1,
x => x * 2,
);
const promise = Promise.resolve(1);
promise.then(
pipe(
x => x + 1,
x => x * 2,
),
);
// #29904.4
declare const getString: () => string;
declare const orUndefined: (name: string) => string | undefined;
declare const identity: <T>(value: T) => T;
const fn40 = pipe(
getString,
string => orUndefined(string),
identity,
);
// #29904.6
declare const getArray: () => string[];
declare const first: <T>(ts: T[]) => T;
const fn60 = pipe(
getArray,
x => x,
first,
);
const fn61 = pipe(
getArray,
identity,
first,
);
const fn62 = pipe(
getArray,
x => x,
x => first(x),
);
//// [genericFunctionInference1.js]
const f00 = pipe(list);
const f01 = pipe(list, box);
const f02 = pipe(box, list);
const f03 = pipe(x => list(x), box);
const f04 = pipe(list, x => box(x));
const f05 = pipe(x => list(x), x => box(x));
const f06 = pipe(list, pipe(box));
const f07 = pipe(x => list(x), pipe(box));
const f08 = pipe(x => list(x), pipe(x => box(x)));
const f09 = pipe(list, x => x.length);
const f10 = pipe(foo);
const f11 = pipe(foo, foo);
const g00 = pipe(list);
const g01 = pipe(list, box);
const g02 = pipe(box, list);
const g03 = pipe(x => list(x), box);
const g04 = pipe(list, x => box(x));
const g05 = pipe(x => list(x), x => box(x));
const g06 = pipe(list, pipe(box));
const g07 = pipe(x => list(x), pipe(box));
const g08 = pipe(x => list(x), pipe(x => box(x)));
const g09 = pipe(list, x => x.length);
const g10 = pipe(foo);
const g12 = pipe(foo, foo);
const f20 = pipe2(list, box);
const f21 = pipe2(box, list);
const f22 = pipe2(list, list);
const f23 = pipe2(box, box);
const f24 = pipe2(f20, f20);
const f25 = pipe2(foo, foo);
const f26 = pipe2(f25, f25);
const f30 = pipe3(list, box);
const f31 = pipe3(box, list);
const f32 = pipe3(list, list);
const f40 = pipe4([list, box]);
const f41 = pipe4([box, list]);
const f50 = pipe5(list); // No higher order inference
// #417
function mirror(f) { return f; }
var identityM = mirror(identity);
var x = 1;
var y = identity(x);
var z = identityM(x);
// #3038
export function keyOf(value) {
return value.key;
}
var data = [];
toKeys(data, keyOf); // Error
// #9366
function flip(f) {
return (b, a) => f(a, b);
}
function zip(x, y) {
return [x, y];
}
var expected = flip(zip);
var actual = flip(zip);
// #9366
const map = (transform) => (arr) => arr.map(transform);
const identityStr = (t) => t;
const arr = map(identityStr)(['a']);
const arr1 = map(identity)(['a']);
// #9949
function of2(one, two) {
return [one, two];
}
const flipped = flip(of2);
const enhance = pipe(myHoc1, myHoc2);
const MyComponent2 = enhance(MyComponent1);
// #29904.2
const fn20 = pipe((_a) => 1);
const fn30 = pipe(x => x + 1, x => x * 2);
const promise = Promise.resolve(1);
promise.then(pipe(x => x + 1, x => x * 2));
const fn40 = pipe(getString, string => orUndefined(string), identity);
const fn60 = pipe(getArray, x => x, first);
const fn61 = pipe(getArray, identity, first);
const fn62 = pipe(getArray, x => x, x => first(x));

View File

@@ -0,0 +1,850 @@
=== tests/cases/compiler/genericFunctionInference1.ts ===
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 0, 42))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 0, 47))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 0, 67))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 1, 45))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 1, 50))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
>bc : Symbol(bc, Decl(genericFunctionInference1.ts, 1, 67))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 1, 73))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 1, 87))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 2, 48))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 2, 53))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
>bc : Symbol(bc, Decl(genericFunctionInference1.ts, 2, 70))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 2, 76))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
>cd : Symbol(cd, Decl(genericFunctionInference1.ts, 2, 87))
>c : Symbol(c, Decl(genericFunctionInference1.ts, 2, 93))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
>args : Symbol(args, Decl(genericFunctionInference1.ts, 2, 107))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
declare function list<T>(a: T): T[];
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 4, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
declare function box<V>(x: V): { value: V };
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 5, 24))
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 5, 32))
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
declare function foo<T extends { value: T }>(x: T): T;
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 6, 32))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 6, 45))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
const f00 = pipe(list);
>f00 : Symbol(f00, Decl(genericFunctionInference1.ts, 8, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const f01 = pipe(list, box);
>f01 : Symbol(f01, Decl(genericFunctionInference1.ts, 9, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f02 = pipe(box, list);
>f02 : Symbol(f02, Decl(genericFunctionInference1.ts, 10, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const f03 = pipe(x => list(x), box);
>f03 : Symbol(f03, Decl(genericFunctionInference1.ts, 11, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 11, 17))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 11, 17))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f04 = pipe(list, x => box(x));
>f04 : Symbol(f04, Decl(genericFunctionInference1.ts, 12, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 12, 22))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 12, 22))
const f05 = pipe(x => list(x), x => box(x))
>f05 : Symbol(f05, Decl(genericFunctionInference1.ts, 13, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 17))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 17))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 30))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 30))
const f06 = pipe(list, pipe(box));
>f06 : Symbol(f06, Decl(genericFunctionInference1.ts, 14, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f07 = pipe(x => list(x), pipe(box));
>f07 : Symbol(f07, Decl(genericFunctionInference1.ts, 15, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 15, 17))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 15, 17))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f08 = pipe(x => list(x), pipe(x => box(x)));
>f08 : Symbol(f08, Decl(genericFunctionInference1.ts, 16, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 17))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 17))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 36))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 36))
const f09 = pipe(list, x => x.length);
>f09 : Symbol(f09, Decl(genericFunctionInference1.ts, 17, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 17, 22))
>x.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 17, 22))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
const f10 = pipe(foo);
>f10 : Symbol(f10, Decl(genericFunctionInference1.ts, 18, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
const f11 = pipe(foo, foo);
>f11 : Symbol(f11, Decl(genericFunctionInference1.ts, 19, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
const g00: <T>(x: T) => T[] = pipe(list);
>g00 : Symbol(g00, Decl(genericFunctionInference1.ts, 21, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 21, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
>g01 : Symbol(g01, Decl(genericFunctionInference1.ts, 22, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 22, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 22, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
>g02 : Symbol(g02, Decl(genericFunctionInference1.ts, 23, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 23, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 23, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
>g03 : Symbol(g03, Decl(genericFunctionInference1.ts, 24, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 24, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 46))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 46))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
>g04 : Symbol(g04, Decl(genericFunctionInference1.ts, 25, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 25, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 51))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 51))
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
>g05 : Symbol(g05, Decl(genericFunctionInference1.ts, 26, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 26, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 46))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 46))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 59))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 59))
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
>g06 : Symbol(g06, Decl(genericFunctionInference1.ts, 27, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 27, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 27, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
>g07 : Symbol(g07, Decl(genericFunctionInference1.ts, 28, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 28, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 46))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 46))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
>g08 : Symbol(g08, Decl(genericFunctionInference1.ts, 29, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 29, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 46))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 46))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 65))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 65))
const g09: <T>(x: T) => number = pipe(list, x => x.length);
>g09 : Symbol(g09, Decl(genericFunctionInference1.ts, 30, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 30, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 30, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 43))
>x.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 43))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
>g10 : Symbol(g10, Decl(genericFunctionInference1.ts, 31, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 31, 23))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 31, 36))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
>g12 : Symbol(g12, Decl(genericFunctionInference1.ts, 32, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 32, 23))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 32, 36))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 34, 35))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 34, 40))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
>cd : Symbol(cd, Decl(genericFunctionInference1.ts, 34, 51))
>c : Symbol(c, Decl(genericFunctionInference1.ts, 34, 57))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 34, 71))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
const f20 = pipe2(list, box);
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f21 = pipe2(box, list);
>f21 : Symbol(f21, Decl(genericFunctionInference1.ts, 37, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const f22 = pipe2(list, list);
>f22 : Symbol(f22, Decl(genericFunctionInference1.ts, 38, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const f23 = pipe2(box, box);
>f23 : Symbol(f23, Decl(genericFunctionInference1.ts, 39, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f24 = pipe2(f20, f20);
>f24 : Symbol(f24, Decl(genericFunctionInference1.ts, 40, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
const f25 = pipe2(foo, foo);
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
const f26 = pipe2(f25, f25);
>f26 : Symbol(f26, Decl(genericFunctionInference1.ts, 42, 5))
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 44, 32))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 37))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
>ac : Symbol(ac, Decl(genericFunctionInference1.ts, 44, 48))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 54))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 68))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
const f30 = pipe3(list, box);
>f30 : Symbol(f30, Decl(genericFunctionInference1.ts, 46, 5))
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f31 = pipe3(box, list);
>f31 : Symbol(f31, Decl(genericFunctionInference1.ts, 47, 5))
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
const f32 = pipe3(list, list);
>f32 : Symbol(f32, Decl(genericFunctionInference1.ts, 48, 5))
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
>funcs : Symbol(funcs, Decl(genericFunctionInference1.ts, 50, 32))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 50, 41))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 50, 54))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 50, 69))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
const f40 = pipe4([list, box]);
>f40 : Symbol(f40, Decl(genericFunctionInference1.ts, 52, 5))
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
const f41 = pipe4([box, list]);
>f41 : Symbol(f41, Decl(genericFunctionInference1.ts, 53, 5))
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
>pipe5 : Symbol(pipe5, Decl(genericFunctionInference1.ts, 53, 31))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 55, 29))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 55, 33))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 55, 47))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 55, 52))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
const f50 = pipe5(list); // No higher order inference
>f50 : Symbol(f50, Decl(genericFunctionInference1.ts, 57, 5))
>pipe5 : Symbol(pipe5, Decl(genericFunctionInference1.ts, 53, 31))
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
// #417
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
>mirror : Symbol(mirror, Decl(genericFunctionInference1.ts, 57, 24))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 61, 22))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 61, 26))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 61, 40))
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 61, 22))
var identityM = mirror(identity);
>identityM : Symbol(identityM, Decl(genericFunctionInference1.ts, 62, 3))
>mirror : Symbol(mirror, Decl(genericFunctionInference1.ts, 57, 24))
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
var x = 1;
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
var y = identity(x);
>y : Symbol(y, Decl(genericFunctionInference1.ts, 65, 3))
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
var z = identityM(x);
>z : Symbol(z, Decl(genericFunctionInference1.ts, 66, 3))
>identityM : Symbol(identityM, Decl(genericFunctionInference1.ts, 62, 3))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
// #3038
export function keyOf<a>(value: { key: a; }): a {
>keyOf : Symbol(keyOf, Decl(genericFunctionInference1.ts, 66, 21))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 70, 25))
>key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
return value.key;
>value.key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 70, 25))
>key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
}
export interface Data {
>Data : Symbol(Data, Decl(genericFunctionInference1.ts, 72, 1))
key: number;
>key : Symbol(Data.key, Decl(genericFunctionInference1.ts, 73, 23))
value: Date;
>value : Symbol(Data.value, Decl(genericFunctionInference1.ts, 74, 16))
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
}
var data: Data[] = [];
>data : Symbol(data, Decl(genericFunctionInference1.ts, 78, 3))
>Data : Symbol(Data, Decl(genericFunctionInference1.ts, 72, 1))
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
>toKeys : Symbol(toKeys, Decl(genericFunctionInference1.ts, 78, 22))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
>values : Symbol(values, Decl(genericFunctionInference1.ts, 80, 27))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
>toKey : Symbol(toKey, Decl(genericFunctionInference1.ts, 80, 39))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 80, 48))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
toKeys(data, keyOf); // Error
>toKeys : Symbol(toKeys, Decl(genericFunctionInference1.ts, 78, 22))
>data : Symbol(data, Decl(genericFunctionInference1.ts, 78, 3))
>keyOf : Symbol(keyOf, Decl(genericFunctionInference1.ts, 66, 21))
// #9366
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 86, 23))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 27))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 32))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 47))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 52))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
return (b: b, a: a) => f(a, b);
>b : Symbol(b, Decl(genericFunctionInference1.ts, 87, 10))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 87, 15))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
>f : Symbol(f, Decl(genericFunctionInference1.ts, 86, 23))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 87, 15))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 87, 10))
}
function zip<T, U>(x: T, y: U): [T, U] {
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 89, 19))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
>y : Symbol(y, Decl(genericFunctionInference1.ts, 89, 24))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
return [x, y];
>x : Symbol(x, Decl(genericFunctionInference1.ts, 89, 19))
>y : Symbol(y, Decl(genericFunctionInference1.ts, 89, 24))
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
>expected : Symbol(expected, Decl(genericFunctionInference1.ts, 93, 3))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
>y : Symbol(y, Decl(genericFunctionInference1.ts, 93, 21))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 93, 26))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
var actual = flip(zip);
>actual : Symbol(actual, Decl(genericFunctionInference1.ts, 94, 3))
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
// #9366
const map = <T, U>(transform: (t: T) => U) =>
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 98, 15))
>transform : Symbol(transform, Decl(genericFunctionInference1.ts, 98, 19))
>t : Symbol(t, Decl(genericFunctionInference1.ts, 98, 31))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
>U : Symbol(U, Decl(genericFunctionInference1.ts, 98, 15))
(arr: T[]) => arr.map(transform)
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 99, 5))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
>arr.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 99, 5))
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
>transform : Symbol(transform, Decl(genericFunctionInference1.ts, 98, 19))
const identityStr = (t: string) => t;
>identityStr : Symbol(identityStr, Decl(genericFunctionInference1.ts, 101, 5))
>t : Symbol(t, Decl(genericFunctionInference1.ts, 101, 21))
>t : Symbol(t, Decl(genericFunctionInference1.ts, 101, 21))
const arr: string[] = map(identityStr)(['a']);
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 103, 5))
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
>identityStr : Symbol(identityStr, Decl(genericFunctionInference1.ts, 101, 5))
const arr1: string[] = map(identity)(['a']);
>arr1 : Symbol(arr1, Decl(genericFunctionInference1.ts, 104, 5))
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
// #9949
function of2<a, b>(one: a, two: b): [a, b] {
>of2 : Symbol(of2, Decl(genericFunctionInference1.ts, 104, 44))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
>one : Symbol(one, Decl(genericFunctionInference1.ts, 108, 19))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
>two : Symbol(two, Decl(genericFunctionInference1.ts, 108, 26))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
return [one, two];
>one : Symbol(one, Decl(genericFunctionInference1.ts, 108, 19))
>two : Symbol(two, Decl(genericFunctionInference1.ts, 108, 26))
}
const flipped = flip(of2);
>flipped : Symbol(flipped, Decl(genericFunctionInference1.ts, 112, 5))
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
>of2 : Symbol(of2, Decl(genericFunctionInference1.ts, 104, 44))
// #29904.1
type Component<P> = (props: P) => {};
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 116, 15))
>props : Symbol(props, Decl(genericFunctionInference1.ts, 116, 21))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 116, 15))
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
>myHoc1 : Symbol(myHoc1, Decl(genericFunctionInference1.ts, 118, 13))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 118, 26))
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
>myHoc2 : Symbol(myHoc2, Decl(genericFunctionInference1.ts, 119, 13))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
>C : Symbol(C, Decl(genericFunctionInference1.ts, 119, 26))
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
declare const MyComponent1: Component<{ foo: 1 }>;
>MyComponent1 : Symbol(MyComponent1, Decl(genericFunctionInference1.ts, 121, 13))
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 121, 39))
const enhance = pipe(
>enhance : Symbol(enhance, Decl(genericFunctionInference1.ts, 123, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
myHoc1,
>myHoc1 : Symbol(myHoc1, Decl(genericFunctionInference1.ts, 118, 13))
myHoc2,
>myHoc2 : Symbol(myHoc2, Decl(genericFunctionInference1.ts, 119, 13))
);
const MyComponent2 = enhance(MyComponent1);
>MyComponent2 : Symbol(MyComponent2, Decl(genericFunctionInference1.ts, 128, 5))
>enhance : Symbol(enhance, Decl(genericFunctionInference1.ts, 123, 5))
>MyComponent1 : Symbol(MyComponent1, Decl(genericFunctionInference1.ts, 121, 13))
// #29904.2
const fn20 = pipe((_a?: {}) => 1);
>fn20 : Symbol(fn20, Decl(genericFunctionInference1.ts, 132, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
>_a : Symbol(_a, Decl(genericFunctionInference1.ts, 132, 19))
// #29904.3
type Fn = (n: number) => number;
>Fn : Symbol(Fn, Decl(genericFunctionInference1.ts, 132, 34))
>n : Symbol(n, Decl(genericFunctionInference1.ts, 136, 11))
const fn30: Fn = pipe(
>fn30 : Symbol(fn30, Decl(genericFunctionInference1.ts, 137, 5))
>Fn : Symbol(Fn, Decl(genericFunctionInference1.ts, 132, 34))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
x => x + 1,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 137, 22))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 137, 22))
x => x * 2,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 138, 15))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 138, 15))
);
const promise = Promise.resolve(1);
>promise : Symbol(promise, Decl(genericFunctionInference1.ts, 142, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
promise.then(
>promise.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
>promise : Symbol(promise, Decl(genericFunctionInference1.ts, 142, 5))
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
pipe(
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
x => x + 1,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 144, 9))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 144, 9))
x => x * 2,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 145, 19))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 145, 19))
),
);
// #29904.4
declare const getString: () => string;
>getString : Symbol(getString, Decl(genericFunctionInference1.ts, 152, 13))
declare const orUndefined: (name: string) => string | undefined;
>orUndefined : Symbol(orUndefined, Decl(genericFunctionInference1.ts, 153, 13))
>name : Symbol(name, Decl(genericFunctionInference1.ts, 153, 28))
declare const identity: <T>(value: T) => T;
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
>value : Symbol(value, Decl(genericFunctionInference1.ts, 154, 28))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
const fn40 = pipe(
>fn40 : Symbol(fn40, Decl(genericFunctionInference1.ts, 156, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
getString,
>getString : Symbol(getString, Decl(genericFunctionInference1.ts, 152, 13))
string => orUndefined(string),
>string : Symbol(string, Decl(genericFunctionInference1.ts, 157, 14))
>orUndefined : Symbol(orUndefined, Decl(genericFunctionInference1.ts, 153, 13))
>string : Symbol(string, Decl(genericFunctionInference1.ts, 157, 14))
identity,
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
);
// #29904.6
declare const getArray: () => string[];
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
declare const first: <T>(ts: T[]) => T;
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
>ts : Symbol(ts, Decl(genericFunctionInference1.ts, 165, 25))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
const fn60 = pipe(
>fn60 : Symbol(fn60, Decl(genericFunctionInference1.ts, 167, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
getArray,
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
x => x,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 168, 13))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 168, 13))
first,
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
);
const fn61 = pipe(
>fn61 : Symbol(fn61, Decl(genericFunctionInference1.ts, 173, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
getArray,
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
identity,
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
first,
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
);
const fn62 = pipe(
>fn62 : Symbol(fn62, Decl(genericFunctionInference1.ts, 179, 5))
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
getArray,
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
x => x,
>x : Symbol(x, Decl(genericFunctionInference1.ts, 180, 13))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 180, 13))
x => first(x),
>x : Symbol(x, Decl(genericFunctionInference1.ts, 181, 11))
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
>x : Symbol(x, Decl(genericFunctionInference1.ts, 181, 11))
);

View File

@@ -0,0 +1,801 @@
=== tests/cases/compiler/genericFunctionInference1.ts ===
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>ab : (...args: A) => B
>args : A
>args : A
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>ab : (...args: A) => B
>args : A
>bc : (b: B) => C
>b : B
>args : A
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>ab : (...args: A) => B
>args : A
>bc : (b: B) => C
>b : B
>cd : (c: C) => D
>c : C
>args : A
declare function list<T>(a: T): T[];
>list : <T>(a: T) => T[]
>a : T
declare function box<V>(x: V): { value: V };
>box : <V>(x: V) => { value: V; }
>x : V
>value : V
declare function foo<T extends { value: T }>(x: T): T;
>foo : <T extends { value: T; }>(x: T) => T
>value : T
>x : T
const f00 = pipe(list);
>f00 : <T>(a: T) => T[]
>pipe(list) : <T>(a: T) => T[]
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
const f01 = pipe(list, box);
>f01 : <T>(a: T) => { value: T[]; }
>pipe(list, box) : <T>(a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>box : <V>(x: V) => { value: V; }
const f02 = pipe(box, list);
>f02 : <V>(x: V) => { value: V; }[]
>pipe(box, list) : <V>(x: V) => { value: V; }[]
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
>list : <T>(a: T) => T[]
const f03 = pipe(x => list(x), box);
>f03 : (x: any) => { value: any[]; }
>pipe(x => list(x), box) : (x: any) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: any) => any[]
>x : any
>list(x) : any[]
>list : <T>(a: T) => T[]
>x : any
>box : <V>(x: V) => { value: V; }
const f04 = pipe(list, x => box(x));
>f04 : <T>(a: T) => { value: T[]; }
>pipe(list, x => box(x)) : <T>(a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>x => box(x) : (x: T[]) => { value: T[]; }
>x : T[]
>box(x) : { value: T[]; }
>box : <V>(x: V) => { value: V; }
>x : T[]
const f05 = pipe(x => list(x), x => box(x))
>f05 : (x: any) => { value: any[]; }
>pipe(x => list(x), x => box(x)) : (x: any) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: any) => any[]
>x : any
>list(x) : any[]
>list : <T>(a: T) => T[]
>x : any
>x => box(x) : (x: any[]) => { value: any[]; }
>x : any[]
>box(x) : { value: any[]; }
>box : <V>(x: V) => { value: V; }
>x : any[]
const f06 = pipe(list, pipe(box));
>f06 : <T>(a: T) => { value: T[]; }
>pipe(list, pipe(box)) : <T>(a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>pipe(box) : (x: T[]) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
const f07 = pipe(x => list(x), pipe(box));
>f07 : (x: any) => { value: any[]; }
>pipe(x => list(x), pipe(box)) : (x: any) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: any) => any[]
>x : any
>list(x) : any[]
>list : <T>(a: T) => T[]
>x : any
>pipe(box) : (x: any[]) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
const f08 = pipe(x => list(x), pipe(x => box(x)));
>f08 : (x: any) => { value: any[]; }
>pipe(x => list(x), pipe(x => box(x))) : (x: any) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: any) => any[]
>x : any
>list(x) : any[]
>list : <T>(a: T) => T[]
>x : any
>pipe(x => box(x)) : (x: any[]) => { value: any[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => box(x) : (x: any[]) => { value: any[]; }
>x : any[]
>box(x) : { value: any[]; }
>box : <V>(x: V) => { value: V; }
>x : any[]
const f09 = pipe(list, x => x.length);
>f09 : <T>(a: T) => number
>pipe(list, x => x.length) : <T>(a: T) => number
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>x => x.length : (x: T[]) => number
>x : T[]
>x.length : number
>x : T[]
>length : number
const f10 = pipe(foo);
>f10 : <T extends { value: T; }>(x: T) => T
>pipe(foo) : <T extends { value: T; }>(x: T) => T
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>foo : <T extends { value: T; }>(x: T) => T
const f11 = pipe(foo, foo);
>f11 : <T extends { value: T; }>(x: T) => T
>pipe(foo, foo) : <T extends { value: T; }>(x: T) => T
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>foo : <T extends { value: T; }>(x: T) => T
>foo : <T extends { value: T; }>(x: T) => T
const g00: <T>(x: T) => T[] = pipe(list);
>g00 : <T>(x: T) => T[]
>x : T
>pipe(list) : (a: T) => T[]
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
>g01 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(list, box) : (a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>box : <V>(x: V) => { value: V; }
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
>g02 : <T>(x: T) => { value: T; }[]
>x : T
>value : T
>pipe(box, list) : (x: T) => { value: T; }[]
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
>list : <T>(a: T) => T[]
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
>g03 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(x => list(x), box) : (x: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: T) => T[]
>x : T
>list(x) : T[]
>list : <T>(a: T) => T[]
>x : T
>box : <V>(x: V) => { value: V; }
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
>g04 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(list, x => box(x)) : (a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>x => box(x) : (x: T[]) => { value: T[]; }
>x : T[]
>box(x) : { value: T[]; }
>box : <V>(x: V) => { value: V; }
>x : T[]
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
>g05 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(x => list(x), x => box(x)) : (x: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: T) => T[]
>x : T
>list(x) : T[]
>list : <T>(a: T) => T[]
>x : T
>x => box(x) : (x: T[]) => { value: T[]; }
>x : T[]
>box(x) : { value: T[]; }
>box : <V>(x: V) => { value: V; }
>x : T[]
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
>g06 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(list, pipe(box)) : (a: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>pipe(box) : (x: T[]) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
>g07 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(x => list(x), pipe(box)) : (x: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: T) => T[]
>x : T
>list(x) : T[]
>list : <T>(a: T) => T[]
>x : T
>pipe(box) : (x: T[]) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>box : <V>(x: V) => { value: V; }
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
>g08 : <T>(x: T) => { value: T[]; }
>x : T
>value : T[]
>pipe(x => list(x), pipe(x => box(x))) : (x: T) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => list(x) : (x: T) => T[]
>x : T
>list(x) : T[]
>list : <T>(a: T) => T[]
>x : T
>pipe(x => box(x)) : (x: T[]) => { value: T[]; }
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>x => box(x) : (x: T[]) => { value: T[]; }
>x : T[]
>box(x) : { value: T[]; }
>box : <V>(x: V) => { value: V; }
>x : T[]
const g09: <T>(x: T) => number = pipe(list, x => x.length);
>g09 : <T>(x: T) => number
>x : T
>pipe(list, x => x.length) : (a: T) => number
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>list : <T>(a: T) => T[]
>x => x.length : (x: T[]) => number
>x : T[]
>x.length : number
>x : T[]
>length : number
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
>g10 : <T extends { value: T; }>(x: T) => T
>value : T
>x : T
>pipe(foo) : (x: T) => T
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>foo : <T extends { value: T; }>(x: T) => T
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
>g12 : <T extends { value: T; }>(x: T) => T
>value : T
>x : T
>pipe(foo, foo) : (x: T) => T
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>foo : <T extends { value: T; }>(x: T) => T
>foo : <T extends { value: T; }>(x: T) => T
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>ab : (a: A) => B
>a : A
>cd : (c: C) => D
>c : C
>a : [A, C]
const f20 = pipe2(list, box);
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
>pipe2(list, box) : <T, V>(a: [T, V]) => [T[], { value: V; }]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>list : <T>(a: T) => T[]
>box : <V>(x: V) => { value: V; }
const f21 = pipe2(box, list);
>f21 : <V, T>(a: [V, T]) => [{ value: V; }, T[]]
>pipe2(box, list) : <V, T>(a: [V, T]) => [{ value: V; }, T[]]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>box : <V>(x: V) => { value: V; }
>list : <T>(a: T) => T[]
const f22 = pipe2(list, list);
>f22 : <T, T1>(a: [T, T1]) => [T[], T1[]]
>pipe2(list, list) : <T, T1>(a: [T, T1]) => [T[], T1[]]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>list : <T>(a: T) => T[]
>list : <T>(a: T) => T[]
const f23 = pipe2(box, box);
>f23 : <V, V1>(a: [V, V1]) => [{ value: V; }, { value: V1; }]
>pipe2(box, box) : <V, V1>(a: [V, V1]) => [{ value: V; }, { value: V1; }]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>box : <V>(x: V) => { value: V; }
>box : <V>(x: V) => { value: V; }
const f24 = pipe2(f20, f20);
>f24 : <T, V, T1, V1>(a: [[T, V], [T1, V1]]) => [[T[], { value: V; }], [T1[], { value: V1; }]]
>pipe2(f20, f20) : <T, V, T1, V1>(a: [[T, V], [T1, V1]]) => [[T[], { value: V; }], [T1[], { value: V1; }]]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
const f25 = pipe2(foo, foo);
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
>pipe2(foo, foo) : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>foo : <T extends { value: T; }>(x: T) => T
>foo : <T extends { value: T; }>(x: T) => T
const f26 = pipe2(f25, f25);
>f26 : <T extends { value: T; }, T1 extends { value: T1; }, T2 extends { value: T2; }, T3 extends { value: T3; }>(a: [[T, T1], [T2, T3]]) => [[T, T1], [T2, T3]]
>pipe2(f25, f25) : <T extends { value: T; }, T1 extends { value: T1; }, T2 extends { value: T2; }, T3 extends { value: T3; }>(a: [[T, T1], [T2, T3]]) => [[T, T1], [T2, T3]]
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
>ab : (a: A) => B
>a : A
>ac : (a: A) => C
>a : A
>a : A
const f30 = pipe3(list, box);
>f30 : <T>(a: T) => [T[], { value: T; }]
>pipe3(list, box) : <T>(a: T) => [T[], { value: T; }]
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
>list : <T>(a: T) => T[]
>box : <V>(x: V) => { value: V; }
const f31 = pipe3(box, list);
>f31 : <V>(a: V) => [{ value: V; }, V[]]
>pipe3(box, list) : <V>(a: V) => [{ value: V; }, V[]]
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
>box : <V>(x: V) => { value: V; }
>list : <T>(a: T) => T[]
const f32 = pipe3(list, list);
>f32 : <T>(a: T) => [T[], T[]]
>pipe3(list, list) : <T>(a: T) => [T[], T[]]
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
>list : <T>(a: T) => T[]
>list : <T>(a: T) => T[]
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
>funcs : [(a: A) => B, (b: B) => C]
>a : A
>b : B
>a : A
const f40 = pipe4([list, box]);
>f40 : <T>(a: T) => { value: T[]; }
>pipe4([list, box]) : <T>(a: T) => { value: T[]; }
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
>[list, box] : [<T>(a: T) => T[], <V>(x: V) => { value: V; }]
>list : <T>(a: T) => T[]
>box : <V>(x: V) => { value: V; }
const f41 = pipe4([box, list]);
>f41 : <V>(a: V) => { value: V; }[]
>pipe4([box, list]) : <V>(a: V) => { value: V; }[]
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
>[box, list] : [<V>(x: V) => { value: V; }, <T>(a: T) => T[]]
>box : <V>(x: V) => { value: V; }
>list : <T>(a: T) => T[]
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
>pipe5 : <A, B>(f: (a: A) => B) => { f: (a: A) => B; }
>f : (a: A) => B
>a : A
>f : (a: A) => B
>a : A
const f50 = pipe5(list); // No higher order inference
>f50 : { f: (a: {}) => {}[]; }
>pipe5(list) : { f: (a: {}) => {}[]; }
>pipe5 : <A, B>(f: (a: A) => B) => { f: (a: A) => B; }
>list : <T>(a: T) => T[]
// #417
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
>mirror : <A, B>(f: (a: A) => B) => (a: A) => B
>f : (a: A) => B
>a : A
>a : A
>f : (a: A) => B
var identityM = mirror(identity);
>identityM : <T>(a: T) => T
>mirror(identity) : <T>(a: T) => T
>mirror : <A, B>(f: (a: A) => B) => (a: A) => B
>identity : <T>(value: T) => T
var x = 1;
>x : number
>1 : 1
var y = identity(x);
>y : number
>identity(x) : number
>identity : <T>(value: T) => T
>x : number
var z = identityM(x);
>z : number
>identityM(x) : number
>identityM : <T>(a: T) => T
>x : number
// #3038
export function keyOf<a>(value: { key: a; }): a {
>keyOf : <a>(value: { key: a; }) => a
>value : { key: a; }
>key : a
return value.key;
>value.key : a
>value : { key: a; }
>key : a
}
export interface Data {
key: number;
>key : number
value: Date;
>value : Date
}
var data: Data[] = [];
>data : Data[]
>[] : never[]
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
>toKeys : <a>(values: a[], toKey: (value: a) => string) => string[]
>values : a[]
>toKey : (value: a) => string
>value : a
toKeys(data, keyOf); // Error
>toKeys(data, keyOf) : any
>toKeys : <a>(values: a[], toKey: (value: a) => string) => string[]
>data : Data[]
>keyOf : <a>(value: { key: a; }) => a
// #9366
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
>f : (a: a, b: b) => c
>a : a
>b : b
>b : b
>a : a
return (b: b, a: a) => f(a, b);
>(b: b, a: a) => f(a, b) : (b: b, a: a) => c
>b : b
>a : a
>f(a, b) : c
>f : (a: a, b: b) => c
>a : a
>b : b
}
function zip<T, U>(x: T, y: U): [T, U] {
>zip : <T, U>(x: T, y: U) => [T, U]
>x : T
>y : U
return [x, y];
>[x, y] : [T, U]
>x : T
>y : U
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
>expected : <T, U>(y: U, x: T) => [T, U]
>y : U
>x : T
>flip(zip) : (b: U, a: T) => [T, U]
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
>zip : <T, U>(x: T, y: U) => [T, U]
var actual = flip(zip);
>actual : <T, U>(b: U, a: T) => [T, U]
>flip(zip) : <T, U>(b: U, a: T) => [T, U]
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
>zip : <T, U>(x: T, y: U) => [T, U]
// #9366
const map = <T, U>(transform: (t: T) => U) =>
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
><T, U>(transform: (t: T) => U) => (arr: T[]) => arr.map(transform) : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
>transform : (t: T) => U
>t : T
(arr: T[]) => arr.map(transform)
>(arr: T[]) => arr.map(transform) : (arr: T[]) => U[]
>arr : T[]
>arr.map(transform) : U[]
>arr.map : <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]
>arr : T[]
>map : <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]
>transform : (t: T) => U
const identityStr = (t: string) => t;
>identityStr : (t: string) => string
>(t: string) => t : (t: string) => string
>t : string
>t : string
const arr: string[] = map(identityStr)(['a']);
>arr : string[]
>map(identityStr)(['a']) : string[]
>map(identityStr) : (arr: string[]) => string[]
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
>identityStr : (t: string) => string
>['a'] : string[]
>'a' : "a"
const arr1: string[] = map(identity)(['a']);
>arr1 : string[]
>map(identity)(['a']) : string[]
>map(identity) : <T>(arr: T[]) => T[]
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
>identity : <T>(value: T) => T
>['a'] : string[]
>'a' : "a"
// #9949
function of2<a, b>(one: a, two: b): [a, b] {
>of2 : <a, b>(one: a, two: b) => [a, b]
>one : a
>two : b
return [one, two];
>[one, two] : [a, b]
>one : a
>two : b
}
const flipped = flip(of2);
>flipped : <a, b>(b: b, a: a) => [a, b]
>flip(of2) : <a, b>(b: b, a: a) => [a, b]
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
>of2 : <a, b>(one: a, two: b) => [a, b]
// #29904.1
type Component<P> = (props: P) => {};
>Component : Component<P>
>props : P
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
>myHoc1 : <P>(C: Component<P>) => Component<P>
>C : Component<P>
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
>myHoc2 : <P>(C: Component<P>) => Component<P>
>C : Component<P>
declare const MyComponent1: Component<{ foo: 1 }>;
>MyComponent1 : Component<{ foo: 1; }>
>foo : 1
const enhance = pipe(
>enhance : <P>(C: Component<P>) => Component<P>
>pipe( myHoc1, myHoc2,) : <P>(C: Component<P>) => Component<P>
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
myHoc1,
>myHoc1 : <P>(C: Component<P>) => Component<P>
myHoc2,
>myHoc2 : <P>(C: Component<P>) => Component<P>
);
const MyComponent2 = enhance(MyComponent1);
>MyComponent2 : Component<{ foo: 1; }>
>enhance(MyComponent1) : Component<{ foo: 1; }>
>enhance : <P>(C: Component<P>) => Component<P>
>MyComponent1 : Component<{ foo: 1; }>
// #29904.2
const fn20 = pipe((_a?: {}) => 1);
>fn20 : (_a?: {} | undefined) => number
>pipe((_a?: {}) => 1) : (_a?: {} | undefined) => number
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
>(_a?: {}) => 1 : (_a?: {} | undefined) => number
>_a : {} | undefined
>1 : 1
// #29904.3
type Fn = (n: number) => number;
>Fn : Fn
>n : number
const fn30: Fn = pipe(
>fn30 : Fn
>pipe( x => x + 1, x => x * 2,) : (x: number) => number
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
x => x + 1,
>x => x + 1 : (x: number) => number
>x : number
>x + 1 : number
>x : number
>1 : 1
x => x * 2,
>x => x * 2 : (x: number) => number
>x : number
>x * 2 : number
>x : number
>2 : 2
);
const promise = Promise.resolve(1);
>promise : Promise<number>
>Promise.resolve(1) : Promise<number>
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>Promise : PromiseConstructor
>resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>1 : 1
promise.then(
>promise.then( pipe( x => x + 1, x => x * 2, ),) : Promise<number>
>promise.then : <TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
>promise : Promise<number>
>then : <TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
pipe(
>pipe( x => x + 1, x => x * 2, ) : (x: number) => number
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
x => x + 1,
>x => x + 1 : (x: number) => number
>x : number
>x + 1 : number
>x : number
>1 : 1
x => x * 2,
>x => x * 2 : (x: number) => number
>x : number
>x * 2 : number
>x : number
>2 : 2
),
);
// #29904.4
declare const getString: () => string;
>getString : () => string
declare const orUndefined: (name: string) => string | undefined;
>orUndefined : (name: string) => string | undefined
>name : string
declare const identity: <T>(value: T) => T;
>identity : <T>(value: T) => T
>value : T
const fn40 = pipe(
>fn40 : () => string | undefined
>pipe( getString, string => orUndefined(string), identity,) : () => string | undefined
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
getString,
>getString : () => string
string => orUndefined(string),
>string => orUndefined(string) : (string: string) => string | undefined
>string : string
>orUndefined(string) : string | undefined
>orUndefined : (name: string) => string | undefined
>string : string
identity,
>identity : <T>(value: T) => T
);
// #29904.6
declare const getArray: () => string[];
>getArray : () => string[]
declare const first: <T>(ts: T[]) => T;
>first : <T>(ts: T[]) => T
>ts : T[]
const fn60 = pipe(
>fn60 : () => string
>pipe( getArray, x => x, first,) : () => string
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
getArray,
>getArray : () => string[]
x => x,
>x => x : (x: string[]) => string[]
>x : string[]
>x : string[]
first,
>first : <T>(ts: T[]) => T
);
const fn61 = pipe(
>fn61 : () => string
>pipe( getArray, identity, first,) : () => string
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
getArray,
>getArray : () => string[]
identity,
>identity : <T>(value: T) => T
first,
>first : <T>(ts: T[]) => T
);
const fn62 = pipe(
>fn62 : () => string
>pipe( getArray, x => x, x => first(x),) : () => string
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
getArray,
>getArray : () => string[]
x => x,
>x => x : (x: string[]) => string[]
>x : string[]
>x : string[]
x => first(x),
>x => first(x) : (x: string[]) => string
>x : string[]
>first(x) : string
>first : <T>(ts: T[]) => T
>x : string[]
);

View File

@@ -309,7 +309,7 @@ declare function f16<A, B>(a: A, b: B): A | B;
declare let x20: number;
declare let x21: string;
declare let x22: string | number;
declare let x23: unknown;
declare let x23: string | number;
declare let x24: string | number;
declare let x30: string;
declare let x31: string | number;

View File

@@ -462,8 +462,8 @@ let x22 = call(f15, "hello", 42); // string | number
>42 : 42
let x23 = call(f16, "hello", 42); // unknown
>x23 : unknown
>call(f16, "hello", 42) : unknown
>x23 : string | number
>call(f16, "hello", 42) : string | number
>call : <T extends unknown[], U>(f: (...args: T) => U, ...args: T) => U
>f16 : <A, B>(a: A, b: B) => A | B
>"hello" : "hello"

View File

@@ -129,8 +129,8 @@ function curry1<A, B, C>(f: (a: A, b: B) => C): (ax: A) => (bx: B) => C {
}
var cfilter = curry1(filter);
>cfilter : (ax: {}) => (bx: {}) => {}[]
>curry1(filter) : (ax: {}) => (bx: {}) => {}[]
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
>curry1(filter) : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
>curry1 : <A, B, C>(f: (a: A, b: B) => C) => (ax: A) => (bx: B) => C
>filter : <A>(f: (a: A) => boolean, ar: A[]) => A[]
@@ -149,11 +149,11 @@ function countWhere_1<A>(pred: (a: A) => boolean): (a: A[]) => number {
>a : A[]
return compose(length2, cfilter(pred));
>compose(length2, cfilter(pred)) : (a: {}) => number
>compose(length2, cfilter(pred)) : (a: A[]) => number
>compose : <A, B, C>(f: (b: B) => C, g: (a: A) => B) => (a: A) => C
>length2 : <A>(ar: A[]) => number
>cfilter(pred) : (bx: {}) => {}[]
>cfilter : (ax: {}) => (bx: {}) => {}[]
>cfilter(pred) : (bx: A[]) => A[]
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
>pred : (a: A) => boolean
}
@@ -164,14 +164,14 @@ function countWhere_2<A>(pred: (a: A) => boolean): (a: A[]) => number {
>a : A[]
var where = cfilter(pred);
>where : (bx: {}) => {}[]
>cfilter(pred) : (bx: {}) => {}[]
>cfilter : (ax: {}) => (bx: {}) => {}[]
>where : (bx: A[]) => A[]
>cfilter(pred) : (bx: A[]) => A[]
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
>pred : (a: A) => boolean
return compose(length2, where);
>compose(length2, where) : (a: {}) => number
>compose(length2, where) : (a: A[]) => number
>compose : <A, B, C>(f: (b: B) => C, g: (a: A) => B) => (a: A) => C
>length2 : <A>(ar: A[]) => number
>where : (bx: {}) => {}[]
>where : (bx: A[]) => A[]
}

View File

@@ -0,0 +1,187 @@
// @strict: true
// @target: es2015
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
declare function list<T>(a: T): T[];
declare function box<V>(x: V): { value: V };
declare function foo<T extends { value: T }>(x: T): T;
const f00 = pipe(list);
const f01 = pipe(list, box);
const f02 = pipe(box, list);
const f03 = pipe(x => list(x), box);
const f04 = pipe(list, x => box(x));
const f05 = pipe(x => list(x), x => box(x))
const f06 = pipe(list, pipe(box));
const f07 = pipe(x => list(x), pipe(box));
const f08 = pipe(x => list(x), pipe(x => box(x)));
const f09 = pipe(list, x => x.length);
const f10 = pipe(foo);
const f11 = pipe(foo, foo);
const g00: <T>(x: T) => T[] = pipe(list);
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
const g09: <T>(x: T) => number = pipe(list, x => x.length);
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
const f20 = pipe2(list, box);
const f21 = pipe2(box, list);
const f22 = pipe2(list, list);
const f23 = pipe2(box, box);
const f24 = pipe2(f20, f20);
const f25 = pipe2(foo, foo);
const f26 = pipe2(f25, f25);
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
const f30 = pipe3(list, box);
const f31 = pipe3(box, list);
const f32 = pipe3(list, list);
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
const f40 = pipe4([list, box]);
const f41 = pipe4([box, list]);
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
const f50 = pipe5(list); // No higher order inference
// #417
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
var identityM = mirror(identity);
var x = 1;
var y = identity(x);
var z = identityM(x);
// #3038
export function keyOf<a>(value: { key: a; }): a {
return value.key;
}
export interface Data {
key: number;
value: Date;
}
var data: Data[] = [];
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
toKeys(data, keyOf); // Error
// #9366
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
return (b: b, a: a) => f(a, b);
}
function zip<T, U>(x: T, y: U): [T, U] {
return [x, y];
}
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
var actual = flip(zip);
// #9366
const map = <T, U>(transform: (t: T) => U) =>
(arr: T[]) => arr.map(transform)
const identityStr = (t: string) => t;
const arr: string[] = map(identityStr)(['a']);
const arr1: string[] = map(identity)(['a']);
// #9949
function of2<a, b>(one: a, two: b): [a, b] {
return [one, two];
}
const flipped = flip(of2);
// #29904.1
type Component<P> = (props: P) => {};
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
declare const MyComponent1: Component<{ foo: 1 }>;
const enhance = pipe(
myHoc1,
myHoc2,
);
const MyComponent2 = enhance(MyComponent1);
// #29904.2
const fn20 = pipe((_a?: {}) => 1);
// #29904.3
type Fn = (n: number) => number;
const fn30: Fn = pipe(
x => x + 1,
x => x * 2,
);
const promise = Promise.resolve(1);
promise.then(
pipe(
x => x + 1,
x => x * 2,
),
);
// #29904.4
declare const getString: () => string;
declare const orUndefined: (name: string) => string | undefined;
declare const identity: <T>(value: T) => T;
const fn40 = pipe(
getString,
string => orUndefined(string),
identity,
);
// #29904.6
declare const getArray: () => string[];
declare const first: <T>(ts: T[]) => T;
const fn60 = pipe(
getArray,
x => x,
first,
);
const fn61 = pipe(
getArray,
identity,
first,
);
const fn62 = pipe(
getArray,
x => x,
x => first(x),
);