Revert collecting only outermost intra expression inference sites (#54613)

This commit is contained in:
Mateusz Burzyński 2023-06-12 19:09:07 +02:00 committed by GitHub
parent 4c7dfb6632
commit 9d17b345b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1295 additions and 27 deletions

View File

@ -1254,13 +1254,12 @@ export const enum CheckMode {
Inferential = 1 << 1, // Inferential typing
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
SkipAddingIntraExpressionSites = 1 << 4, // Skip adding intra expression sites in nested expressions since only the outermost one has to be added
IsForSignatureHelp = 1 << 5, // Call resolution for purposes of signature help
IsForStringLiteralArgumentCompletions = 1 << 6, // Do not infer from the argument currently being typed
RestBindingElement = 1 << 7, // Checking a type that is going to be used to determine the type of a rest binding element
IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
IsForStringLiteralArgumentCompletions = 1 << 5, // Do not infer from the argument currently being typed
RestBindingElement = 1 << 6, // Checking a type that is going to be used to determine the type of a rest binding element
// e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
// we need to preserve generic types instead of substituting them for constraints
TypeOnly = 1 << 8, // Called from getTypeOfExpression, diagnostics may be omitted
TypeOnly = 1 << 7, // Called from getTypeOfExpression, diagnostics may be omitted
}
/** @internal */
@ -29990,13 +29989,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
elementFlags.push(ElementFlags.Optional);
}
else {
const shouldAddAsIntraExpressionInferenceSite = inTupleContext && checkMode && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) && isContextSensitive(e);
const elementCheckMode = (checkMode || CheckMode.Normal) | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
const type = checkExpressionForMutableLocation(e, elementCheckMode, forceTuple);
const type = checkExpressionForMutableLocation(e, checkMode, forceTuple);
elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression));
elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required);
if (shouldAddAsIntraExpressionInferenceSite) {
if (inTupleContext && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e)) {
const inferenceContext = getInferenceContext(node);
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
addIntraExpressionInferenceSite(inferenceContext, e, type);
@ -30161,17 +30157,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
isObjectLiteralMethod(memberDecl)) {
const shouldAddAsIntraExpressionInferenceSite = contextualType && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) &&
(memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl);
const propCheckMode = checkMode | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, propCheckMode) :
let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) :
// avoid resolving the left side of the ShorthandPropertyAssignment outside of the destructuring
// for error recovery purposes. For example, if a user wrote `{ a = 100 }` instead of `{ a: 100 }`.
// we don't want to say "could not find 'a'".
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, propCheckMode) :
checkObjectLiteralMethod(memberDecl, propCheckMode);
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode) :
checkObjectLiteralMethod(memberDecl, checkMode);
if (isInJavascript) {
const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
if (jsDocType) {
@ -30226,7 +30217,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
member = prop;
allPropertiesTable?.set(prop.escapedName, prop);
if (shouldAddAsIntraExpressionInferenceSite) {
if (contextualType && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) &&
(memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl)) {
const inferenceContext = getInferenceContext(node);
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
const inferenceNode = memberDecl.kind === SyntaxKind.PropertyAssignment ? memberDecl.initializer : memberDecl;
@ -30460,10 +30452,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
for (const attributeDecl of attributes.properties) {
const member = attributeDecl.symbol;
if (isJsxAttribute(attributeDecl)) {
const shouldAddAsIntraExpressionInferenceSite = contextualType && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) && isContextSensitive(attributeDecl);
const attributeCheckMode = checkMode | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
const exprType = checkJsxAttribute(attributeDecl, attributeCheckMode);
const exprType = checkJsxAttribute(attributeDecl, checkMode);
objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags;
const attributeSymbol = createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
@ -30485,7 +30474,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addDeprecatedSuggestion(attributeDecl.name, prop.declarations, attributeDecl.name.escapedText as string);
}
}
if (shouldAddAsIntraExpressionInferenceSite) {
if (contextualType && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(attributeDecl)) {
const inferenceContext = getInferenceContext(attributes);
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
const inferenceNode = (attributeDecl.initializer as JsxExpression).expression!;

View File

@ -227,4 +227,121 @@ intraExpressionInferences.ts(133,26): error TS2339: Property 'nonexistent' does
arg.toString();
},
},
});
});
declare function nested<T>(arg: {
prop: {
produce: (arg1: number) => T;
consume: (arg2: T) => void;
};
}): T;
const resNested = nested({
prop: {
produce: (a) => [a],
consume: (arg) => arg.join(","),
},
});
declare function twoConsumers<T>(arg: {
a: (arg: string) => T;
consume1: (arg1: T) => void;
consume2: (arg2: T) => void;
}): T;
const resTwoConsumers = twoConsumers({
a: (arg) => [arg],
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
a: (arg: string) => T;
b: (arg: string) => T2;
consume1: (arg1: T) => void;
consume2: (arg2: T2) => void;
}): [T, T2];
const resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
a: (arg) => [arg],
b: (arg) => Number(arg),
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function withConditionalExpression<T, T2, T3>(arg: {
a: (arg1: string) => T;
b: (arg2: T) => T2;
c: (arg2: T2) => T3;
}): [T, T2, T3];
const resWithConditionalExpression = withConditionalExpression({
a: (arg) => [arg],
b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const,
c: (arg) => Boolean(arg),
});
declare function onion<T, T2, T3>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
nested2: {
c: (arg2: T2) => T3;
};
};
}): [T, T2, T3];
const resOnion = onion({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
nested2: {
c: (arg) => Boolean(arg),
},
},
});
declare function onion2<T, T2, T3, T4>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
c: (arg3: T) => T3;
nested2: {
d: (arg4: T3) => T4;
};
};
}): [T, T2, T3, T4];
const resOnion2 = onion2({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
c: (arg) => Number(arg),
nested2: {
d: (arg) => Boolean(arg),
},
},
});
declare function distant<T>(args: {
foo: {
bar: {
baz: {
producer: (arg: string) => T;
};
};
};
consumer: (val: T) => unknown;
}): T;
const distantRes = distant({
foo: {
bar: {
baz: {
producer: (arg) => 1,
},
},
},
consumer: (val) => {},
});

View File

@ -214,7 +214,124 @@ Foo({
arg.toString();
},
},
});
});
declare function nested<T>(arg: {
prop: {
produce: (arg1: number) => T;
consume: (arg2: T) => void;
};
}): T;
const resNested = nested({
prop: {
produce: (a) => [a],
consume: (arg) => arg.join(","),
},
});
declare function twoConsumers<T>(arg: {
a: (arg: string) => T;
consume1: (arg1: T) => void;
consume2: (arg2: T) => void;
}): T;
const resTwoConsumers = twoConsumers({
a: (arg) => [arg],
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
a: (arg: string) => T;
b: (arg: string) => T2;
consume1: (arg1: T) => void;
consume2: (arg2: T2) => void;
}): [T, T2];
const resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
a: (arg) => [arg],
b: (arg) => Number(arg),
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function withConditionalExpression<T, T2, T3>(arg: {
a: (arg1: string) => T;
b: (arg2: T) => T2;
c: (arg2: T2) => T3;
}): [T, T2, T3];
const resWithConditionalExpression = withConditionalExpression({
a: (arg) => [arg],
b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const,
c: (arg) => Boolean(arg),
});
declare function onion<T, T2, T3>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
nested2: {
c: (arg2: T2) => T3;
};
};
}): [T, T2, T3];
const resOnion = onion({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
nested2: {
c: (arg) => Boolean(arg),
},
},
});
declare function onion2<T, T2, T3, T4>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
c: (arg3: T) => T3;
nested2: {
d: (arg4: T3) => T4;
};
};
}): [T, T2, T3, T4];
const resOnion2 = onion2({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
c: (arg) => Number(arg),
nested2: {
d: (arg) => Boolean(arg),
},
},
});
declare function distant<T>(args: {
foo: {
bar: {
baz: {
producer: (arg: string) => T;
};
};
};
consumer: (val: T) => unknown;
}): T;
const distantRes = distant({
foo: {
bar: {
baz: {
producer: (arg) => 1,
},
},
},
consumer: (val) => {},
});
//// [intraExpressionInferences.js]
"use strict";
@ -350,6 +467,57 @@ Foo(__assign({
arg.toString();
},
}));
var resNested = nested({
prop: {
produce: function (a) { return [a]; },
consume: function (arg) { return arg.join(","); },
},
});
var resTwoConsumers = twoConsumers({
a: function (arg) { return [arg]; },
consume1: function (arg1) { },
consume2: function (arg2) { },
});
var resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
a: function (arg) { return [arg]; },
b: function (arg) { return Number(arg); },
consume1: function (arg1) { },
consume2: function (arg2) { },
});
var resWithConditionalExpression = withConditionalExpression({
a: function (arg) { return [arg]; },
b: Math.random() ? function (arg) { return "first"; } : function (arg) { return "two"; },
c: function (arg) { return Boolean(arg); },
});
var resOnion = onion({
a: function (arg) { return [arg]; },
nested: {
b: function (arg) { return arg.join(","); },
nested2: {
c: function (arg) { return Boolean(arg); },
},
},
});
var resOnion2 = onion2({
a: function (arg) { return [arg]; },
nested: {
b: function (arg) { return arg.join(","); },
c: function (arg) { return Number(arg); },
nested2: {
d: function (arg) { return Boolean(arg); },
},
},
});
var distantRes = distant({
foo: {
bar: {
baz: {
producer: function (arg) { return 1; },
},
},
},
consumer: function (val) { },
});
//// [intraExpressionInferences.d.ts]
@ -422,3 +590,61 @@ interface Props<T> {
b: (arg: T) => void;
}
declare function Foo<T>(props: Props<T>): null;
declare function nested<T>(arg: {
prop: {
produce: (arg1: number) => T;
consume: (arg2: T) => void;
};
}): T;
declare const resNested: number[];
declare function twoConsumers<T>(arg: {
a: (arg: string) => T;
consume1: (arg1: T) => void;
consume2: (arg2: T) => void;
}): T;
declare const resTwoConsumers: string[];
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
a: (arg: string) => T;
b: (arg: string) => T2;
consume1: (arg1: T) => void;
consume2: (arg2: T2) => void;
}): [T, T2];
declare const resMultipleProducersBeforeConsumers: [string[], number];
declare function withConditionalExpression<T, T2, T3>(arg: {
a: (arg1: string) => T;
b: (arg2: T) => T2;
c: (arg2: T2) => T3;
}): [T, T2, T3];
declare const resWithConditionalExpression: [string[], "first" | "two", boolean];
declare function onion<T, T2, T3>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
nested2: {
c: (arg2: T2) => T3;
};
};
}): [T, T2, T3];
declare const resOnion: [string[], string, boolean];
declare function onion2<T, T2, T3, T4>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
c: (arg3: T) => T3;
nested2: {
d: (arg4: T3) => T4;
};
};
}): [T, T2, T3, T4];
declare const resOnion2: [string[], string, number, boolean];
declare function distant<T>(args: {
foo: {
bar: {
baz: {
producer: (arg: string) => T;
};
};
};
consumer: (val: T) => unknown;
}): T;
declare const distantRes: number;

View File

@ -670,3 +670,409 @@ Foo({
},
},
});
declare function nested<T>(arg: {
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 213, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 215, 24))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 215, 27))
prop: {
>prop : Symbol(prop, Decl(intraExpressionInferences.ts, 215, 33))
produce: (arg1: number) => T;
>produce : Symbol(produce, Decl(intraExpressionInferences.ts, 216, 9))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 217, 14))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 215, 24))
consume: (arg2: T) => void;
>consume : Symbol(consume, Decl(intraExpressionInferences.ts, 217, 33))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 218, 14))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 215, 24))
};
}): T;
>T : Symbol(T, Decl(intraExpressionInferences.ts, 215, 24))
const resNested = nested({
>resNested : Symbol(resNested, Decl(intraExpressionInferences.ts, 222, 5))
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 213, 3))
prop: {
>prop : Symbol(prop, Decl(intraExpressionInferences.ts, 222, 26))
produce: (a) => [a],
>produce : Symbol(produce, Decl(intraExpressionInferences.ts, 223, 9))
>a : Symbol(a, Decl(intraExpressionInferences.ts, 224, 14))
>a : Symbol(a, Decl(intraExpressionInferences.ts, 224, 14))
consume: (arg) => arg.join(","),
>consume : Symbol(consume, Decl(intraExpressionInferences.ts, 224, 24))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 225, 14))
>arg.join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 225, 14))
>join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
},
});
declare function twoConsumers<T>(arg: {
>twoConsumers : Symbol(twoConsumers, Decl(intraExpressionInferences.ts, 227, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 229, 30))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 229, 33))
a: (arg: string) => T;
>a : Symbol(a, Decl(intraExpressionInferences.ts, 229, 39))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 230, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 229, 30))
consume1: (arg1: T) => void;
>consume1 : Symbol(consume1, Decl(intraExpressionInferences.ts, 230, 24))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 231, 13))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 229, 30))
consume2: (arg2: T) => void;
>consume2 : Symbol(consume2, Decl(intraExpressionInferences.ts, 231, 30))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 232, 13))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 229, 30))
}): T;
>T : Symbol(T, Decl(intraExpressionInferences.ts, 229, 30))
const resTwoConsumers = twoConsumers({
>resTwoConsumers : Symbol(resTwoConsumers, Decl(intraExpressionInferences.ts, 235, 5))
>twoConsumers : Symbol(twoConsumers, Decl(intraExpressionInferences.ts, 227, 3))
a: (arg) => [arg],
>a : Symbol(a, Decl(intraExpressionInferences.ts, 235, 38))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 236, 6))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 236, 6))
consume1: (arg1) => {},
>consume1 : Symbol(consume1, Decl(intraExpressionInferences.ts, 236, 20))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 237, 13))
consume2: (arg2) => {},
>consume2 : Symbol(consume2, Decl(intraExpressionInferences.ts, 237, 25))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 238, 13))
});
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
>multipleProducersBeforeConsumers : Symbol(multipleProducersBeforeConsumers, Decl(intraExpressionInferences.ts, 239, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 241, 50))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 241, 52))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 241, 57))
a: (arg: string) => T;
>a : Symbol(a, Decl(intraExpressionInferences.ts, 241, 63))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 242, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 241, 50))
b: (arg: string) => T2;
>b : Symbol(b, Decl(intraExpressionInferences.ts, 242, 24))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 243, 6))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 241, 52))
consume1: (arg1: T) => void;
>consume1 : Symbol(consume1, Decl(intraExpressionInferences.ts, 243, 25))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 244, 13))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 241, 50))
consume2: (arg2: T2) => void;
>consume2 : Symbol(consume2, Decl(intraExpressionInferences.ts, 244, 30))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 245, 13))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 241, 52))
}): [T, T2];
>T : Symbol(T, Decl(intraExpressionInferences.ts, 241, 50))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 241, 52))
const resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
>resMultipleProducersBeforeConsumers : Symbol(resMultipleProducersBeforeConsumers, Decl(intraExpressionInferences.ts, 248, 5))
>multipleProducersBeforeConsumers : Symbol(multipleProducersBeforeConsumers, Decl(intraExpressionInferences.ts, 239, 3))
a: (arg) => [arg],
>a : Symbol(a, Decl(intraExpressionInferences.ts, 248, 78))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 249, 6))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 249, 6))
b: (arg) => Number(arg),
>b : Symbol(b, Decl(intraExpressionInferences.ts, 249, 20))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 250, 6))
>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 250, 6))
consume1: (arg1) => {},
>consume1 : Symbol(consume1, Decl(intraExpressionInferences.ts, 250, 26))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 251, 13))
consume2: (arg2) => {},
>consume2 : Symbol(consume2, Decl(intraExpressionInferences.ts, 251, 25))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 252, 13))
});
declare function withConditionalExpression<T, T2, T3>(arg: {
>withConditionalExpression : Symbol(withConditionalExpression, Decl(intraExpressionInferences.ts, 253, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 255, 43))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 255, 45))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 255, 49))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 255, 54))
a: (arg1: string) => T;
>a : Symbol(a, Decl(intraExpressionInferences.ts, 255, 60))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 256, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 255, 43))
b: (arg2: T) => T2;
>b : Symbol(b, Decl(intraExpressionInferences.ts, 256, 25))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 257, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 255, 43))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 255, 45))
c: (arg2: T2) => T3;
>c : Symbol(c, Decl(intraExpressionInferences.ts, 257, 21))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 258, 6))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 255, 45))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 255, 49))
}): [T, T2, T3];
>T : Symbol(T, Decl(intraExpressionInferences.ts, 255, 43))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 255, 45))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 255, 49))
const resWithConditionalExpression = withConditionalExpression({
>resWithConditionalExpression : Symbol(resWithConditionalExpression, Decl(intraExpressionInferences.ts, 261, 5))
>withConditionalExpression : Symbol(withConditionalExpression, Decl(intraExpressionInferences.ts, 253, 3))
a: (arg) => [arg],
>a : Symbol(a, Decl(intraExpressionInferences.ts, 261, 64))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 262, 6))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 262, 6))
b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const,
>b : Symbol(b, Decl(intraExpressionInferences.ts, 262, 20))
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 263, 22))
>const : Symbol(const)
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 263, 50))
>const : Symbol(const)
c: (arg) => Boolean(arg),
>c : Symbol(c, Decl(intraExpressionInferences.ts, 263, 73))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 264, 6))
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 264, 6))
});
declare function onion<T, T2, T3>(arg: {
>onion : Symbol(onion, Decl(intraExpressionInferences.ts, 265, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 267, 23))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 267, 25))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 267, 29))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 267, 34))
a: (arg1: string) => T;
>a : Symbol(a, Decl(intraExpressionInferences.ts, 267, 40))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 268, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 267, 23))
nested: {
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 268, 25))
b: (arg2: T) => T2;
>b : Symbol(b, Decl(intraExpressionInferences.ts, 269, 11))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 270, 8))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 267, 23))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 267, 25))
nested2: {
>nested2 : Symbol(nested2, Decl(intraExpressionInferences.ts, 270, 23))
c: (arg2: T2) => T3;
>c : Symbol(c, Decl(intraExpressionInferences.ts, 271, 14))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 272, 10))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 267, 25))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 267, 29))
};
};
}): [T, T2, T3];
>T : Symbol(T, Decl(intraExpressionInferences.ts, 267, 23))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 267, 25))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 267, 29))
const resOnion = onion({
>resOnion : Symbol(resOnion, Decl(intraExpressionInferences.ts, 277, 5))
>onion : Symbol(onion, Decl(intraExpressionInferences.ts, 265, 3))
a: (arg) => [arg],
>a : Symbol(a, Decl(intraExpressionInferences.ts, 277, 24))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 278, 6))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 278, 6))
nested: {
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 278, 20))
b: (arg) => arg.join(","),
>b : Symbol(b, Decl(intraExpressionInferences.ts, 279, 11))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 280, 8))
>arg.join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 280, 8))
>join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
nested2: {
>nested2 : Symbol(nested2, Decl(intraExpressionInferences.ts, 280, 30))
c: (arg) => Boolean(arg),
>c : Symbol(c, Decl(intraExpressionInferences.ts, 281, 14))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 282, 10))
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 282, 10))
},
},
});
declare function onion2<T, T2, T3, T4>(arg: {
>onion2 : Symbol(onion2, Decl(intraExpressionInferences.ts, 285, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 287, 24))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 287, 26))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 287, 30))
>T4 : Symbol(T4, Decl(intraExpressionInferences.ts, 287, 34))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 287, 39))
a: (arg1: string) => T;
>a : Symbol(a, Decl(intraExpressionInferences.ts, 287, 45))
>arg1 : Symbol(arg1, Decl(intraExpressionInferences.ts, 288, 6))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 287, 24))
nested: {
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 288, 25))
b: (arg2: T) => T2;
>b : Symbol(b, Decl(intraExpressionInferences.ts, 289, 11))
>arg2 : Symbol(arg2, Decl(intraExpressionInferences.ts, 290, 8))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 287, 24))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 287, 26))
c: (arg3: T) => T3;
>c : Symbol(c, Decl(intraExpressionInferences.ts, 290, 23))
>arg3 : Symbol(arg3, Decl(intraExpressionInferences.ts, 291, 8))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 287, 24))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 287, 30))
nested2: {
>nested2 : Symbol(nested2, Decl(intraExpressionInferences.ts, 291, 23))
d: (arg4: T3) => T4;
>d : Symbol(d, Decl(intraExpressionInferences.ts, 292, 14))
>arg4 : Symbol(arg4, Decl(intraExpressionInferences.ts, 293, 10))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 287, 30))
>T4 : Symbol(T4, Decl(intraExpressionInferences.ts, 287, 34))
};
};
}): [T, T2, T3, T4];
>T : Symbol(T, Decl(intraExpressionInferences.ts, 287, 24))
>T2 : Symbol(T2, Decl(intraExpressionInferences.ts, 287, 26))
>T3 : Symbol(T3, Decl(intraExpressionInferences.ts, 287, 30))
>T4 : Symbol(T4, Decl(intraExpressionInferences.ts, 287, 34))
const resOnion2 = onion2({
>resOnion2 : Symbol(resOnion2, Decl(intraExpressionInferences.ts, 298, 5))
>onion2 : Symbol(onion2, Decl(intraExpressionInferences.ts, 285, 3))
a: (arg) => [arg],
>a : Symbol(a, Decl(intraExpressionInferences.ts, 298, 26))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 299, 6))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 299, 6))
nested: {
>nested : Symbol(nested, Decl(intraExpressionInferences.ts, 299, 20))
b: (arg) => arg.join(","),
>b : Symbol(b, Decl(intraExpressionInferences.ts, 300, 11))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 301, 8))
>arg.join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 301, 8))
>join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --))
c: (arg) => Number(arg),
>c : Symbol(c, Decl(intraExpressionInferences.ts, 301, 30))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 302, 8))
>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 302, 8))
nested2: {
>nested2 : Symbol(nested2, Decl(intraExpressionInferences.ts, 302, 28))
d: (arg) => Boolean(arg),
>d : Symbol(d, Decl(intraExpressionInferences.ts, 303, 14))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 304, 10))
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 304, 10))
},
},
});
declare function distant<T>(args: {
>distant : Symbol(distant, Decl(intraExpressionInferences.ts, 307, 3))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 309, 25))
>args : Symbol(args, Decl(intraExpressionInferences.ts, 309, 28))
foo: {
>foo : Symbol(foo, Decl(intraExpressionInferences.ts, 309, 35))
bar: {
>bar : Symbol(bar, Decl(intraExpressionInferences.ts, 310, 8))
baz: {
>baz : Symbol(baz, Decl(intraExpressionInferences.ts, 311, 10))
producer: (arg: string) => T;
>producer : Symbol(producer, Decl(intraExpressionInferences.ts, 312, 12))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 313, 19))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 309, 25))
};
};
};
consumer: (val: T) => unknown;
>consumer : Symbol(consumer, Decl(intraExpressionInferences.ts, 316, 4))
>val : Symbol(val, Decl(intraExpressionInferences.ts, 317, 13))
>T : Symbol(T, Decl(intraExpressionInferences.ts, 309, 25))
}): T;
>T : Symbol(T, Decl(intraExpressionInferences.ts, 309, 25))
const distantRes = distant({
>distantRes : Symbol(distantRes, Decl(intraExpressionInferences.ts, 320, 5))
>distant : Symbol(distant, Decl(intraExpressionInferences.ts, 307, 3))
foo: {
>foo : Symbol(foo, Decl(intraExpressionInferences.ts, 320, 28))
bar: {
>bar : Symbol(bar, Decl(intraExpressionInferences.ts, 321, 8))
baz: {
>baz : Symbol(baz, Decl(intraExpressionInferences.ts, 322, 10))
producer: (arg) => 1,
>producer : Symbol(producer, Decl(intraExpressionInferences.ts, 323, 12))
>arg : Symbol(arg, Decl(intraExpressionInferences.ts, 324, 19))
},
},
},
consumer: (val) => {},
>consumer : Symbol(consumer, Decl(intraExpressionInferences.ts, 327, 4))
>val : Symbol(val, Decl(intraExpressionInferences.ts, 328, 13))
});

View File

@ -703,3 +703,417 @@ Foo({
},
},
});
declare function nested<T>(arg: {
>nested : <T>(arg: { prop: { produce: (arg1: number) => T; consume: (arg2: T) => void; }; }) => T
>arg : { prop: { produce: (arg1: number) => T; consume: (arg2: T) => void; }; }
prop: {
>prop : { produce: (arg1: number) => T; consume: (arg2: T) => void; }
produce: (arg1: number) => T;
>produce : (arg1: number) => T
>arg1 : number
consume: (arg2: T) => void;
>consume : (arg2: T) => void
>arg2 : T
};
}): T;
const resNested = nested({
>resNested : number[]
>nested({ prop: { produce: (a) => [a], consume: (arg) => arg.join(","), },}) : number[]
>nested : <T>(arg: { prop: { produce: (arg1: number) => T; consume: (arg2: T) => void; }; }) => T
>{ prop: { produce: (a) => [a], consume: (arg) => arg.join(","), },} : { prop: { produce: (a: number) => number[]; consume: (arg: number[]) => string; }; }
prop: {
>prop : { produce: (a: number) => number[]; consume: (arg: number[]) => string; }
>{ produce: (a) => [a], consume: (arg) => arg.join(","), } : { produce: (a: number) => number[]; consume: (arg: number[]) => string; }
produce: (a) => [a],
>produce : (a: number) => number[]
>(a) => [a] : (a: number) => number[]
>a : number
>[a] : number[]
>a : number
consume: (arg) => arg.join(","),
>consume : (arg: number[]) => string
>(arg) => arg.join(",") : (arg: number[]) => string
>arg : number[]
>arg.join(",") : string
>arg.join : (separator?: string | undefined) => string
>arg : number[]
>join : (separator?: string | undefined) => string
>"," : ","
},
});
declare function twoConsumers<T>(arg: {
>twoConsumers : <T>(arg: { a: (arg: string) => T; consume1: (arg1: T) => void; consume2: (arg2: T) => void; }) => T
>arg : { a: (arg: string) => T; consume1: (arg1: T) => void; consume2: (arg2: T) => void; }
a: (arg: string) => T;
>a : (arg: string) => T
>arg : string
consume1: (arg1: T) => void;
>consume1 : (arg1: T) => void
>arg1 : T
consume2: (arg2: T) => void;
>consume2 : (arg2: T) => void
>arg2 : T
}): T;
const resTwoConsumers = twoConsumers({
>resTwoConsumers : string[]
>twoConsumers({ a: (arg) => [arg], consume1: (arg1) => {}, consume2: (arg2) => {},}) : string[]
>twoConsumers : <T>(arg: { a: (arg: string) => T; consume1: (arg1: T) => void; consume2: (arg2: T) => void; }) => T
>{ a: (arg) => [arg], consume1: (arg1) => {}, consume2: (arg2) => {},} : { a: (arg: string) => string[]; consume1: (arg1: string[]) => void; consume2: (arg2: string[]) => void; }
a: (arg) => [arg],
>a : (arg: string) => string[]
>(arg) => [arg] : (arg: string) => string[]
>arg : string
>[arg] : string[]
>arg : string
consume1: (arg1) => {},
>consume1 : (arg1: string[]) => void
>(arg1) => {} : (arg1: string[]) => void
>arg1 : string[]
consume2: (arg2) => {},
>consume2 : (arg2: string[]) => void
>(arg2) => {} : (arg2: string[]) => void
>arg2 : string[]
});
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
>multipleProducersBeforeConsumers : <T, T2>(arg: { a: (arg: string) => T; b: (arg: string) => T2; consume1: (arg1: T) => void; consume2: (arg2: T2) => void; }) => [T, T2]
>arg : { a: (arg: string) => T; b: (arg: string) => T2; consume1: (arg1: T) => void; consume2: (arg2: T2) => void; }
a: (arg: string) => T;
>a : (arg: string) => T
>arg : string
b: (arg: string) => T2;
>b : (arg: string) => T2
>arg : string
consume1: (arg1: T) => void;
>consume1 : (arg1: T) => void
>arg1 : T
consume2: (arg2: T2) => void;
>consume2 : (arg2: T2) => void
>arg2 : T2
}): [T, T2];
const resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
>resMultipleProducersBeforeConsumers : [string[], number]
>multipleProducersBeforeConsumers({ a: (arg) => [arg], b: (arg) => Number(arg), consume1: (arg1) => {}, consume2: (arg2) => {},}) : [string[], number]
>multipleProducersBeforeConsumers : <T, T2>(arg: { a: (arg: string) => T; b: (arg: string) => T2; consume1: (arg1: T) => void; consume2: (arg2: T2) => void; }) => [T, T2]
>{ a: (arg) => [arg], b: (arg) => Number(arg), consume1: (arg1) => {}, consume2: (arg2) => {},} : { a: (arg: string) => string[]; b: (arg: string) => number; consume1: (arg1: string[]) => void; consume2: (arg2: number) => void; }
a: (arg) => [arg],
>a : (arg: string) => string[]
>(arg) => [arg] : (arg: string) => string[]
>arg : string
>[arg] : string[]
>arg : string
b: (arg) => Number(arg),
>b : (arg: string) => number
>(arg) => Number(arg) : (arg: string) => number
>arg : string
>Number(arg) : number
>Number : NumberConstructor
>arg : string
consume1: (arg1) => {},
>consume1 : (arg1: string[]) => void
>(arg1) => {} : (arg1: string[]) => void
>arg1 : string[]
consume2: (arg2) => {},
>consume2 : (arg2: number) => void
>(arg2) => {} : (arg2: number) => void
>arg2 : number
});
declare function withConditionalExpression<T, T2, T3>(arg: {
>withConditionalExpression : <T, T2, T3>(arg: { a: (arg1: string) => T; b: (arg2: T) => T2; c: (arg2: T2) => T3; }) => [T, T2, T3]
>arg : { a: (arg1: string) => T; b: (arg2: T) => T2; c: (arg2: T2) => T3; }
a: (arg1: string) => T;
>a : (arg1: string) => T
>arg1 : string
b: (arg2: T) => T2;
>b : (arg2: T) => T2
>arg2 : T
c: (arg2: T2) => T3;
>c : (arg2: T2) => T3
>arg2 : T2
}): [T, T2, T3];
const resWithConditionalExpression = withConditionalExpression({
>resWithConditionalExpression : [string[], "first" | "two", boolean]
>withConditionalExpression({ a: (arg) => [arg], b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const, c: (arg) => Boolean(arg),}) : [string[], "first" | "two", boolean]
>withConditionalExpression : <T, T2, T3>(arg: { a: (arg1: string) => T; b: (arg2: T) => T2; c: (arg2: T2) => T3; }) => [T, T2, T3]
>{ a: (arg) => [arg], b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const, c: (arg) => Boolean(arg),} : { a: (arg: string) => string[]; b: ((arg: string[]) => "first") | ((arg: string[]) => "two"); c: (arg: "first" | "two") => boolean; }
a: (arg) => [arg],
>a : (arg: string) => string[]
>(arg) => [arg] : (arg: string) => string[]
>arg : string
>[arg] : string[]
>arg : string
b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const,
>b : ((arg: string[]) => "first") | ((arg: string[]) => "two")
>Math.random() ? (arg) => "first" as const : (arg) => "two" as const : ((arg: string[]) => "first") | ((arg: string[]) => "two")
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>(arg) => "first" as const : (arg: string[]) => "first"
>arg : string[]
>"first" as const : "first"
>"first" : "first"
>(arg) => "two" as const : (arg: string[]) => "two"
>arg : string[]
>"two" as const : "two"
>"two" : "two"
c: (arg) => Boolean(arg),
>c : (arg: "first" | "two") => boolean
>(arg) => Boolean(arg) : (arg: "first" | "two") => boolean
>arg : "first" | "two"
>Boolean(arg) : boolean
>Boolean : BooleanConstructor
>arg : "first" | "two"
});
declare function onion<T, T2, T3>(arg: {
>onion : <T, T2, T3>(arg: { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; nested2: { c: (arg2: T2) => T3; }; }; }) => [T, T2, T3]
>arg : { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; nested2: { c: (arg2: T2) => T3; }; }; }
a: (arg1: string) => T;
>a : (arg1: string) => T
>arg1 : string
nested: {
>nested : { b: (arg2: T) => T2; nested2: { c: (arg2: T2) => T3; }; }
b: (arg2: T) => T2;
>b : (arg2: T) => T2
>arg2 : T
nested2: {
>nested2 : { c: (arg2: T2) => T3; }
c: (arg2: T2) => T3;
>c : (arg2: T2) => T3
>arg2 : T2
};
};
}): [T, T2, T3];
const resOnion = onion({
>resOnion : [string[], string, boolean]
>onion({ a: (arg) => [arg], nested: { b: (arg) => arg.join(","), nested2: { c: (arg) => Boolean(arg), }, },}) : [string[], string, boolean]
>onion : <T, T2, T3>(arg: { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; nested2: { c: (arg2: T2) => T3; }; }; }) => [T, T2, T3]
>{ a: (arg) => [arg], nested: { b: (arg) => arg.join(","), nested2: { c: (arg) => Boolean(arg), }, },} : { a: (arg: string) => string[]; nested: { b: (arg: string[]) => string; nested2: { c: (arg: string) => boolean; }; }; }
a: (arg) => [arg],
>a : (arg: string) => string[]
>(arg) => [arg] : (arg: string) => string[]
>arg : string
>[arg] : string[]
>arg : string
nested: {
>nested : { b: (arg: string[]) => string; nested2: { c: (arg: string) => boolean; }; }
>{ b: (arg) => arg.join(","), nested2: { c: (arg) => Boolean(arg), }, } : { b: (arg: string[]) => string; nested2: { c: (arg: string) => boolean; }; }
b: (arg) => arg.join(","),
>b : (arg: string[]) => string
>(arg) => arg.join(",") : (arg: string[]) => string
>arg : string[]
>arg.join(",") : string
>arg.join : (separator?: string | undefined) => string
>arg : string[]
>join : (separator?: string | undefined) => string
>"," : ","
nested2: {
>nested2 : { c: (arg: string) => boolean; }
>{ c: (arg) => Boolean(arg), } : { c: (arg: string) => boolean; }
c: (arg) => Boolean(arg),
>c : (arg: string) => boolean
>(arg) => Boolean(arg) : (arg: string) => boolean
>arg : string
>Boolean(arg) : boolean
>Boolean : BooleanConstructor
>arg : string
},
},
});
declare function onion2<T, T2, T3, T4>(arg: {
>onion2 : <T, T2, T3, T4>(arg: { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; c: (arg3: T) => T3; nested2: { d: (arg4: T3) => T4; }; }; }) => [T, T2, T3, T4]
>arg : { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; c: (arg3: T) => T3; nested2: { d: (arg4: T3) => T4; }; }; }
a: (arg1: string) => T;
>a : (arg1: string) => T
>arg1 : string
nested: {
>nested : { b: (arg2: T) => T2; c: (arg3: T) => T3; nested2: { d: (arg4: T3) => T4; }; }
b: (arg2: T) => T2;
>b : (arg2: T) => T2
>arg2 : T
c: (arg3: T) => T3;
>c : (arg3: T) => T3
>arg3 : T
nested2: {
>nested2 : { d: (arg4: T3) => T4; }
d: (arg4: T3) => T4;
>d : (arg4: T3) => T4
>arg4 : T3
};
};
}): [T, T2, T3, T4];
const resOnion2 = onion2({
>resOnion2 : [string[], string, number, boolean]
>onion2({ a: (arg) => [arg], nested: { b: (arg) => arg.join(","), c: (arg) => Number(arg), nested2: { d: (arg) => Boolean(arg), }, },}) : [string[], string, number, boolean]
>onion2 : <T, T2, T3, T4>(arg: { a: (arg1: string) => T; nested: { b: (arg2: T) => T2; c: (arg3: T) => T3; nested2: { d: (arg4: T3) => T4; }; }; }) => [T, T2, T3, T4]
>{ a: (arg) => [arg], nested: { b: (arg) => arg.join(","), c: (arg) => Number(arg), nested2: { d: (arg) => Boolean(arg), }, },} : { a: (arg: string) => string[]; nested: { b: (arg: string[]) => string; c: (arg: string[]) => number; nested2: { d: (arg: number) => boolean; }; }; }
a: (arg) => [arg],
>a : (arg: string) => string[]
>(arg) => [arg] : (arg: string) => string[]
>arg : string
>[arg] : string[]
>arg : string
nested: {
>nested : { b: (arg: string[]) => string; c: (arg: string[]) => number; nested2: { d: (arg: number) => boolean; }; }
>{ b: (arg) => arg.join(","), c: (arg) => Number(arg), nested2: { d: (arg) => Boolean(arg), }, } : { b: (arg: string[]) => string; c: (arg: string[]) => number; nested2: { d: (arg: number) => boolean; }; }
b: (arg) => arg.join(","),
>b : (arg: string[]) => string
>(arg) => arg.join(",") : (arg: string[]) => string
>arg : string[]
>arg.join(",") : string
>arg.join : (separator?: string | undefined) => string
>arg : string[]
>join : (separator?: string | undefined) => string
>"," : ","
c: (arg) => Number(arg),
>c : (arg: string[]) => number
>(arg) => Number(arg) : (arg: string[]) => number
>arg : string[]
>Number(arg) : number
>Number : NumberConstructor
>arg : string[]
nested2: {
>nested2 : { d: (arg: number) => boolean; }
>{ d: (arg) => Boolean(arg), } : { d: (arg: number) => boolean; }
d: (arg) => Boolean(arg),
>d : (arg: number) => boolean
>(arg) => Boolean(arg) : (arg: number) => boolean
>arg : number
>Boolean(arg) : boolean
>Boolean : BooleanConstructor
>arg : number
},
},
});
declare function distant<T>(args: {
>distant : <T>(args: { foo: { bar: { baz: { producer: (arg: string) => T; }; }; }; consumer: (val: T) => unknown; }) => T
>args : { foo: { bar: { baz: { producer: (arg: string) => T; }; }; }; consumer: (val: T) => unknown; }
foo: {
>foo : { bar: { baz: { producer: (arg: string) => T; }; }; }
bar: {
>bar : { baz: { producer: (arg: string) => T; }; }
baz: {
>baz : { producer: (arg: string) => T; }
producer: (arg: string) => T;
>producer : (arg: string) => T
>arg : string
};
};
};
consumer: (val: T) => unknown;
>consumer : (val: T) => unknown
>val : T
}): T;
const distantRes = distant({
>distantRes : number
>distant({ foo: { bar: { baz: { producer: (arg) => 1, }, }, }, consumer: (val) => {},}) : number
>distant : <T>(args: { foo: { bar: { baz: { producer: (arg: string) => T; }; }; }; consumer: (val: T) => unknown; }) => T
>{ foo: { bar: { baz: { producer: (arg) => 1, }, }, }, consumer: (val) => {},} : { foo: { bar: { baz: { producer: (arg: string) => number; }; }; }; consumer: (val: number) => void; }
foo: {
>foo : { bar: { baz: { producer: (arg: string) => number; }; }; }
>{ bar: { baz: { producer: (arg) => 1, }, }, } : { bar: { baz: { producer: (arg: string) => number; }; }; }
bar: {
>bar : { baz: { producer: (arg: string) => number; }; }
>{ baz: { producer: (arg) => 1, }, } : { baz: { producer: (arg: string) => number; }; }
baz: {
>baz : { producer: (arg: string) => number; }
>{ producer: (arg) => 1, } : { producer: (arg: string) => number; }
producer: (arg) => 1,
>producer : (arg: string) => number
>(arg) => 1 : (arg: string) => number
>arg : string
>1 : 1
},
},
},
consumer: (val) => {},
>consumer : (val: number) => void
>(val) => {} : (val: number) => void
>val : number
});

View File

@ -214,4 +214,120 @@ Foo({
arg.toString();
},
},
});
});
declare function nested<T>(arg: {
prop: {
produce: (arg1: number) => T;
consume: (arg2: T) => void;
};
}): T;
const resNested = nested({
prop: {
produce: (a) => [a],
consume: (arg) => arg.join(","),
},
});
declare function twoConsumers<T>(arg: {
a: (arg: string) => T;
consume1: (arg1: T) => void;
consume2: (arg2: T) => void;
}): T;
const resTwoConsumers = twoConsumers({
a: (arg) => [arg],
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function multipleProducersBeforeConsumers<T, T2>(arg: {
a: (arg: string) => T;
b: (arg: string) => T2;
consume1: (arg1: T) => void;
consume2: (arg2: T2) => void;
}): [T, T2];
const resMultipleProducersBeforeConsumers = multipleProducersBeforeConsumers({
a: (arg) => [arg],
b: (arg) => Number(arg),
consume1: (arg1) => {},
consume2: (arg2) => {},
});
declare function withConditionalExpression<T, T2, T3>(arg: {
a: (arg1: string) => T;
b: (arg2: T) => T2;
c: (arg2: T2) => T3;
}): [T, T2, T3];
const resWithConditionalExpression = withConditionalExpression({
a: (arg) => [arg],
b: Math.random() ? (arg) => "first" as const : (arg) => "two" as const,
c: (arg) => Boolean(arg),
});
declare function onion<T, T2, T3>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
nested2: {
c: (arg2: T2) => T3;
};
};
}): [T, T2, T3];
const resOnion = onion({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
nested2: {
c: (arg) => Boolean(arg),
},
},
});
declare function onion2<T, T2, T3, T4>(arg: {
a: (arg1: string) => T;
nested: {
b: (arg2: T) => T2;
c: (arg3: T) => T3;
nested2: {
d: (arg4: T3) => T4;
};
};
}): [T, T2, T3, T4];
const resOnion2 = onion2({
a: (arg) => [arg],
nested: {
b: (arg) => arg.join(","),
c: (arg) => Number(arg),
nested2: {
d: (arg) => Boolean(arg),
},
},
});
declare function distant<T>(args: {
foo: {
bar: {
baz: {
producer: (arg: string) => T;
};
};
};
consumer: (val: T) => unknown;
}): T;
const distantRes = distant({
foo: {
bar: {
baz: {
producer: (arg) => 1,
},
},
},
consumer: (val) => {},
});