mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-20 10:29:36 -06:00
Generate a unique type parameter name for each nested type parameter (#31544)
* Generate a unique type parameter name for each nested type parameter * Add testcase from 31605 * Fix typo * Liiiiiine eeeendingggggss
This commit is contained in:
parent
daf0a73346
commit
6839973bf7
@ -3699,14 +3699,10 @@ namespace ts {
|
||||
return createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, /*constraintNode*/ undefined));
|
||||
}
|
||||
if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
|
||||
type.flags & TypeFlags.TypeParameter &&
|
||||
length(type.symbol.declarations) &&
|
||||
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
|
||||
typeParameterShadowsNameInScope(type, context) &&
|
||||
!isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
|
||||
const name = (type.symbol.declarations[0] as TypeParameterDeclaration).name;
|
||||
const name = typeParameterToName(type, context);
|
||||
context.approximateLength += idText(name).length;
|
||||
return createTypeReferenceNode(getGeneratedNameForNode(name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes), /*typeArguments*/ undefined);
|
||||
return createTypeReferenceNode(createIdentifier(idText(name)), /*typeArguments*/ undefined);
|
||||
}
|
||||
// Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
|
||||
return type.symbol
|
||||
@ -4237,21 +4233,10 @@ namespace ts {
|
||||
return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
|
||||
}
|
||||
|
||||
function typeParameterShadowsNameInScope(type: TypeParameter, context: NodeBuilderContext) {
|
||||
return !!resolveName(context.enclosingDeclaration, type.symbol.escapedName, SymbolFlags.Type, /*nameNotFoundArg*/ undefined, type.symbol.escapedName, /*isUse*/ false);
|
||||
}
|
||||
|
||||
function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration {
|
||||
const savedContextFlags = context.flags;
|
||||
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 && type.symbol.declarations[0] &&
|
||||
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
|
||||
typeParameterShadowsNameInScope(type, context);
|
||||
const name = shouldUseGeneratedName
|
||||
? getGeneratedNameForNode((type.symbol.declarations[0] as TypeParameterDeclaration).name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes)
|
||||
: symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true);
|
||||
const name = typeParameterToName(type, context);
|
||||
const defaultParameter = getDefaultFromTypeParameter(type);
|
||||
const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
|
||||
context.flags = savedContextFlags;
|
||||
@ -4584,6 +4569,35 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function typeParameterShadowsNameInScope(escapedName: __String, context: NodeBuilderContext) {
|
||||
return !!resolveName(context.enclosingDeclaration, escapedName, SymbolFlags.Type, /*nameNotFoundArg*/ undefined, escapedName, /*isUse*/ false);
|
||||
}
|
||||
|
||||
function typeParameterToName(type: TypeParameter, context: NodeBuilderContext) {
|
||||
if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && context.typeParameterNames) {
|
||||
const cached = context.typeParameterNames.get("" + getTypeId(type));
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
let result = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true);
|
||||
if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) {
|
||||
const rawtext = result.escapedText as string;
|
||||
let i = 0;
|
||||
let text = rawtext;
|
||||
while ((context.typeParameterNamesByText && context.typeParameterNamesByText.get(text)) || typeParameterShadowsNameInScope(text as __String, context)) {
|
||||
i++;
|
||||
text = `${rawtext}_${i}`;
|
||||
}
|
||||
if (text !== rawtext) {
|
||||
result = createIdentifier(text, result.typeArguments);
|
||||
}
|
||||
(context.typeParameterNames || (context.typeParameterNames = createMap())).set("" + getTypeId(type), result);
|
||||
(context.typeParameterNamesByText || (context.typeParameterNamesByText = createMap())).set(result.escapedText as string, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier;
|
||||
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName;
|
||||
function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName {
|
||||
@ -4745,6 +4759,8 @@ namespace ts {
|
||||
approximateLength: number;
|
||||
truncating?: boolean;
|
||||
typeParameterSymbolList?: Map<true>;
|
||||
typeParameterNames?: Map<Identifier>;
|
||||
typeParameterNamesByText?: Map<true>;
|
||||
}
|
||||
|
||||
function isDefaultBindingContext(location: Node) {
|
||||
|
||||
@ -0,0 +1,164 @@
|
||||
//// [declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts]
|
||||
// Note that both of the following have an `any` in their return type from where we bottom out the type printout
|
||||
// for having too many instances of the same symbol nesting.
|
||||
|
||||
// Slightly simplified repro from https://github.com/microsoft/TypeScript/issues/30732 so it's easier to read and debug
|
||||
export type Key<U> = keyof U;
|
||||
export type Value<K extends Key<U>, U> = U[K];
|
||||
export const updateIfChanged = <T>(t: T) => {
|
||||
const reduce = <U>(u: U, update: (u: U) => T) => {
|
||||
const set = (newU: U) => Object.is(u, newU) ? t : update(newU);
|
||||
return Object.assign(
|
||||
<K extends Key<U>>(key: K) =>
|
||||
reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => {
|
||||
return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v }));
|
||||
}),
|
||||
{ map: (updater: (u: U) => U) => set(updater(u)), set });
|
||||
};
|
||||
return reduce<T>(t, (t: T) => t);
|
||||
};
|
||||
|
||||
// example from https://github.com/microsoft/TypeScript/issues/31605
|
||||
|
||||
export const testRecFun = <T extends Object>(parent: T) => {
|
||||
return {
|
||||
result: parent,
|
||||
deeper: <U extends Object>(child: U) =>
|
||||
testRecFun<T & U>({ ...parent, ...child })
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let p1 = testRecFun({ one: '1' })
|
||||
void p1.result.one;
|
||||
let p2 = p1.deeper({ two: '2' })
|
||||
void p2.result.one;
|
||||
void p2.result.two;
|
||||
let p3 = p2.deeper({ three: '3' })
|
||||
void p3.result.one;
|
||||
void p3.result.two;
|
||||
void p3.result.three;
|
||||
|
||||
|
||||
//// [declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.js]
|
||||
"use strict";
|
||||
// Note that both of the following have an `any` in their return type from where we bottom out the type printout
|
||||
// for having too many instances of the same symbol nesting.
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.updateIfChanged = function (t) {
|
||||
var reduce = function (u, update) {
|
||||
var set = function (newU) { return Object.is(u, newU) ? t : update(newU); };
|
||||
return Object.assign(function (key) {
|
||||
return reduce(u[key], function (v) {
|
||||
var _a;
|
||||
return update(Object.assign(Array.isArray(u) ? [] : {}, u, (_a = {}, _a[key] = v, _a)));
|
||||
});
|
||||
}, { map: function (updater) { return set(updater(u)); }, set: set });
|
||||
};
|
||||
return reduce(t, function (t) { return t; });
|
||||
};
|
||||
// example from https://github.com/microsoft/TypeScript/issues/31605
|
||||
exports.testRecFun = function (parent) {
|
||||
return {
|
||||
result: parent,
|
||||
deeper: function (child) {
|
||||
return exports.testRecFun(__assign({}, parent, child));
|
||||
}
|
||||
};
|
||||
};
|
||||
var p1 = exports.testRecFun({ one: '1' });
|
||||
void p1.result.one;
|
||||
var p2 = p1.deeper({ two: '2' });
|
||||
void p2.result.one;
|
||||
void p2.result.two;
|
||||
var p3 = p2.deeper({ three: '3' });
|
||||
void p3.result.one;
|
||||
void p3.result.two;
|
||||
void p3.result.three;
|
||||
|
||||
|
||||
//// [declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.d.ts]
|
||||
export declare type Key<U> = keyof U;
|
||||
export declare type Value<K extends Key<U>, U> = U[K];
|
||||
export declare const updateIfChanged: <T>(t: T) => (<K extends keyof T>(key: K) => (<K_1 extends keyof T[K]>(key: K_1) => (<K_2 extends keyof T[K][K_1]>(key: K_2) => (<K_3 extends keyof T[K][K_1][K_2]>(key: K_3) => (<K_4 extends keyof T[K][K_1][K_2][K_3]>(key: K_4) => (<K_5 extends keyof T[K][K_1][K_2][K_3][K_4]>(key: K_5) => (<K_6 extends keyof T[K][K_1][K_2][K_3][K_4][K_5]>(key: K_6) => (<K_7 extends keyof T[K][K_1][K_2][K_3][K_4][K_5][K_6]>(key: K_7) => (<K_8 extends keyof T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>(key: K_8) => (<K_9 extends keyof T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>(key: K_9) => (<K_10 extends keyof T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>(key: K_10) => any & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]) => T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]) => T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]) => T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]) => T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5][K_6]) => T[K][K_1][K_2][K_3][K_4][K_5][K_6]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5][K_6]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4][K_5]) => T[K][K_1][K_2][K_3][K_4][K_5]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4][K_5]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3][K_4]) => T[K][K_1][K_2][K_3][K_4]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3][K_4]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2][K_3]) => T[K][K_1][K_2][K_3]) => T;
|
||||
set: (newU: T[K][K_1][K_2][K_3]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1][K_2]) => T[K][K_1][K_2]) => T;
|
||||
set: (newU: T[K][K_1][K_2]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K][K_1]) => T[K][K_1]) => T;
|
||||
set: (newU: T[K][K_1]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T[K]) => T[K]) => T;
|
||||
set: (newU: T[K]) => T;
|
||||
}) & {
|
||||
map: (updater: (u: T) => T) => T;
|
||||
set: (newU: T) => T;
|
||||
};
|
||||
export declare const testRecFun: <T extends Object>(parent: T) => {
|
||||
result: T;
|
||||
deeper: <U extends Object>(child: U) => {
|
||||
result: T & U;
|
||||
deeper: <U_1 extends Object>(child: U_1) => {
|
||||
result: T & U & U_1;
|
||||
deeper: <U_2 extends Object>(child: U_2) => {
|
||||
result: T & U & U_1 & U_2;
|
||||
deeper: <U_3 extends Object>(child: U_3) => {
|
||||
result: T & U & U_1 & U_2 & U_3;
|
||||
deeper: <U_4 extends Object>(child: U_4) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4;
|
||||
deeper: <U_5 extends Object>(child: U_5) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4 & U_5;
|
||||
deeper: <U_6 extends Object>(child: U_6) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4 & U_5 & U_6;
|
||||
deeper: <U_7 extends Object>(child: U_7) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4 & U_5 & U_6 & U_7;
|
||||
deeper: <U_8 extends Object>(child: U_8) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4 & U_5 & U_6 & U_7 & U_8;
|
||||
deeper: <U_9 extends Object>(child: U_9) => {
|
||||
result: T & U & U_1 & U_2 & U_3 & U_4 & U_5 & U_6 & U_7 & U_8 & U_9;
|
||||
deeper: <U_10 extends Object>(child: U_10) => any;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,206 @@
|
||||
=== tests/cases/compiler/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts ===
|
||||
// Note that both of the following have an `any` in their return type from where we bottom out the type printout
|
||||
// for having too many instances of the same symbol nesting.
|
||||
|
||||
// Slightly simplified repro from https://github.com/microsoft/TypeScript/issues/30732 so it's easier to read and debug
|
||||
export type Key<U> = keyof U;
|
||||
>Key : Symbol(Key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 16))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 16))
|
||||
|
||||
export type Value<K extends Key<U>, U> = U[K];
|
||||
>Value : Symbol(Value, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 29))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 5, 18))
|
||||
>Key : Symbol(Key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 5, 35))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 5, 35))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 5, 35))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 5, 18))
|
||||
|
||||
export const updateIfChanged = <T>(t: T) => {
|
||||
>updateIfChanged : Symbol(updateIfChanged, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 12))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 32))
|
||||
>t : Symbol(t, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 35))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 32))
|
||||
|
||||
const reduce = <U>(u: U, update: (u: U) => T) => {
|
||||
>reduce : Symbol(reduce, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 9))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>update : Symbol(update, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 28))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 38))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 32))
|
||||
|
||||
const set = (newU: U) => Object.is(u, newU) ? t : update(newU);
|
||||
>set : Symbol(set, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 8, 13))
|
||||
>newU : Symbol(newU, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 8, 21))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>Object.is : Symbol(ObjectConstructor.is, Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>is : Symbol(ObjectConstructor.is, Decl(lib.es2015.core.d.ts, --, --))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>newU : Symbol(newU, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 8, 21))
|
||||
>t : Symbol(t, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 35))
|
||||
>update : Symbol(update, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 28))
|
||||
>newU : Symbol(newU, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 8, 21))
|
||||
|
||||
return Object.assign(
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
|
||||
<K extends Key<U>>(key: K) =>
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 13))
|
||||
>Key : Symbol(Key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>key : Symbol(key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 31))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 13))
|
||||
|
||||
reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => {
|
||||
>reduce : Symbol(reduce, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 9))
|
||||
>Value : Symbol(Value, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 29))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 13))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>key : Symbol(key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 31))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>Value : Symbol(Value, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 29))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 13))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>v : Symbol(v, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 11, 71))
|
||||
>Value : Symbol(Value, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 4, 29))
|
||||
>K : Symbol(K, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 13))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
|
||||
return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v }));
|
||||
>update : Symbol(update, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 28))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>[key] : Symbol([key], Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 12, 80))
|
||||
>key : Symbol(key, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 10, 31))
|
||||
>v : Symbol(v, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 11, 71))
|
||||
|
||||
}),
|
||||
{ map: (updater: (u: U) => U) => set(updater(u)), set });
|
||||
>map : Symbol(map, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 14, 13))
|
||||
>updater : Symbol(updater, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 14, 20))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 14, 30))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 20))
|
||||
>set : Symbol(set, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 8, 13))
|
||||
>updater : Symbol(updater, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 14, 20))
|
||||
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
|
||||
>set : Symbol(set, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 14, 61))
|
||||
|
||||
};
|
||||
return reduce<T>(t, (t: T) => t);
|
||||
>reduce : Symbol(reduce, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 9))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 32))
|
||||
>t : Symbol(t, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 35))
|
||||
>t : Symbol(t, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 16, 25))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 6, 32))
|
||||
>t : Symbol(t, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 16, 25))
|
||||
|
||||
};
|
||||
|
||||
// example from https://github.com/microsoft/TypeScript/issues/31605
|
||||
|
||||
export const testRecFun = <T extends Object>(parent: T) => {
|
||||
>testRecFun : Symbol(testRecFun, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 12))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 27))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>parent : Symbol(parent, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 45))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 27))
|
||||
|
||||
return {
|
||||
result: parent,
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>parent : Symbol(parent, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 45))
|
||||
|
||||
deeper: <U extends Object>(child: U) =>
|
||||
>deeper : Symbol(deeper, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 23, 23))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 24, 17))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>child : Symbol(child, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 24, 35))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 24, 17))
|
||||
|
||||
testRecFun<T & U>({ ...parent, ...child })
|
||||
>testRecFun : Symbol(testRecFun, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 12))
|
||||
>T : Symbol(T, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 27))
|
||||
>U : Symbol(U, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 24, 17))
|
||||
>parent : Symbol(parent, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 45))
|
||||
>child : Symbol(child, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 24, 35))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let p1 = testRecFun({ one: '1' })
|
||||
>p1 : Symbol(p1, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 3))
|
||||
>testRecFun : Symbol(testRecFun, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 21, 12))
|
||||
>one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
|
||||
void p1.result.one;
|
||||
>p1.result.one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
>p1.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p1 : Symbol(p1, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
|
||||
let p2 = p1.deeper({ two: '2' })
|
||||
>p2 : Symbol(p2, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 3))
|
||||
>p1.deeper : Symbol(deeper, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 23, 23))
|
||||
>p1 : Symbol(p1, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 3))
|
||||
>deeper : Symbol(deeper, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 23, 23))
|
||||
>two : Symbol(two, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 20))
|
||||
|
||||
void p2.result.one;
|
||||
>p2.result.one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
>p2.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p2 : Symbol(p2, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
|
||||
void p2.result.two;
|
||||
>p2.result.two : Symbol(two, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 20))
|
||||
>p2.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p2 : Symbol(p2, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>two : Symbol(two, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 20))
|
||||
|
||||
let p3 = p2.deeper({ three: '3' })
|
||||
>p3 : Symbol(p3, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 3))
|
||||
>p2.deeper : Symbol(deeper, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 23, 23))
|
||||
>p2 : Symbol(p2, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 3))
|
||||
>deeper : Symbol(deeper, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 23, 23))
|
||||
>three : Symbol(three, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 20))
|
||||
|
||||
void p3.result.one;
|
||||
>p3.result.one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
>p3.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p3 : Symbol(p3, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>one : Symbol(one, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 30, 21))
|
||||
|
||||
void p3.result.two;
|
||||
>p3.result.two : Symbol(two, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 20))
|
||||
>p3.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p3 : Symbol(p3, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>two : Symbol(two, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 32, 20))
|
||||
|
||||
void p3.result.three;
|
||||
>p3.result.three : Symbol(three, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 20))
|
||||
>p3.result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>p3 : Symbol(p3, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 3))
|
||||
>result : Symbol(result, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 22, 12))
|
||||
>three : Symbol(three, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 35, 20))
|
||||
|
||||
@ -0,0 +1,212 @@
|
||||
=== tests/cases/compiler/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts ===
|
||||
// Note that both of the following have an `any` in their return type from where we bottom out the type printout
|
||||
// for having too many instances of the same symbol nesting.
|
||||
|
||||
// Slightly simplified repro from https://github.com/microsoft/TypeScript/issues/30732 so it's easier to read and debug
|
||||
export type Key<U> = keyof U;
|
||||
>Key : keyof U
|
||||
|
||||
export type Value<K extends Key<U>, U> = U[K];
|
||||
>Value : U[K]
|
||||
|
||||
export const updateIfChanged = <T>(t: T) => {
|
||||
>updateIfChanged : <T>(t: T) => (<K extends keyof T>(key: K) => (<K extends keyof T[K]>(key: K) => (<K extends keyof T[K][K]>(key: K) => (<K extends keyof T[K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K]) => T[K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K]) => T[K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K]) => T[K][K][K][K]) => T; set: (newU: T[K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K]) => T[K][K][K]) => T; set: (newU: T[K][K][K]) => T; }) & { map: (updater: (u: T[K][K]) => T[K][K]) => T; set: (newU: T[K][K]) => T; }) & { map: (updater: (u: T[K]) => T[K]) => T; set: (newU: T[K]) => T; }) & { map: (updater: (u: T) => T) => T; set: (newU: T) => T; }
|
||||
><T>(t: T) => { const reduce = <U>(u: U, update: (u: U) => T) => { const set = (newU: U) => Object.is(u, newU) ? t : update(newU); return Object.assign( <K extends Key<U>>(key: K) => reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); }), { map: (updater: (u: U) => U) => set(updater(u)), set }); }; return reduce<T>(t, (t: T) => t);} : <T>(t: T) => (<K extends keyof T>(key: K) => (<K extends keyof T[K]>(key: K) => (<K extends keyof T[K][K]>(key: K) => (<K extends keyof T[K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K]) => T[K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K]) => T[K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K]) => T[K][K][K][K]) => T; set: (newU: T[K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K]) => T[K][K][K]) => T; set: (newU: T[K][K][K]) => T; }) & { map: (updater: (u: T[K][K]) => T[K][K]) => T; set: (newU: T[K][K]) => T; }) & { map: (updater: (u: T[K]) => T[K]) => T; set: (newU: T[K]) => T; }) & { map: (updater: (u: T) => T) => T; set: (newU: T) => T; }
|
||||
>t : T
|
||||
|
||||
const reduce = <U>(u: U, update: (u: U) => T) => {
|
||||
>reduce : <U>(u: U, update: (u: U) => T) => (<K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }) & { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
><U>(u: U, update: (u: U) => T) => { const set = (newU: U) => Object.is(u, newU) ? t : update(newU); return Object.assign( <K extends Key<U>>(key: K) => reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); }), { map: (updater: (u: U) => U) => set(updater(u)), set }); } : <U>(u: U, update: (u: U) => T) => (<K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }) & { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
>u : U
|
||||
>update : (u: U) => T
|
||||
>u : U
|
||||
|
||||
const set = (newU: U) => Object.is(u, newU) ? t : update(newU);
|
||||
>set : (newU: U) => T
|
||||
>(newU: U) => Object.is(u, newU) ? t : update(newU) : (newU: U) => T
|
||||
>newU : U
|
||||
>Object.is(u, newU) ? t : update(newU) : T
|
||||
>Object.is(u, newU) : boolean
|
||||
>Object.is : (value1: any, value2: any) => boolean
|
||||
>Object : ObjectConstructor
|
||||
>is : (value1: any, value2: any) => boolean
|
||||
>u : U
|
||||
>newU : U
|
||||
>t : T
|
||||
>update(newU) : T
|
||||
>update : (u: U) => T
|
||||
>newU : U
|
||||
|
||||
return Object.assign(
|
||||
>Object.assign( <K extends Key<U>>(key: K) => reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); }), { map: (updater: (u: U) => U) => set(updater(u)), set }) : (<K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }) & { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
|
||||
<K extends Key<U>>(key: K) =>
|
||||
><K extends Key<U>>(key: K) => reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); }) : <K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }
|
||||
>key : K
|
||||
|
||||
reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => {
|
||||
>reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); }) : (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }
|
||||
>reduce : <U>(u: U, update: (u: U) => T) => (<K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }) & { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
>u[key as keyof U] as Value<K, U> : U[K]
|
||||
>u[key as keyof U] : U[keyof U]
|
||||
>u : U
|
||||
>key as keyof U : keyof U
|
||||
>key : K
|
||||
>(v: Value<K, U>) => { return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })); } : (v: U[K]) => T
|
||||
>v : U[K]
|
||||
|
||||
return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v }));
|
||||
>update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v })) : T
|
||||
>update : (u: U) => T
|
||||
>Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v }) : U & { [x: string]: U[K]; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Array.isArray(u) ? [] : {} : undefined[] | {}
|
||||
>Array.isArray(u) : boolean
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>u : U
|
||||
>[] : undefined[]
|
||||
>{} : {}
|
||||
>u : U
|
||||
>{ [key]: v } : { [x: string]: U[K]; }
|
||||
>[key] : U[K]
|
||||
>key : K
|
||||
>v : U[K]
|
||||
|
||||
}),
|
||||
{ map: (updater: (u: U) => U) => set(updater(u)), set });
|
||||
>{ map: (updater: (u: U) => U) => set(updater(u)), set } : { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
>map : (updater: (u: U) => U) => T
|
||||
>(updater: (u: U) => U) => set(updater(u)) : (updater: (u: U) => U) => T
|
||||
>updater : (u: U) => U
|
||||
>u : U
|
||||
>set(updater(u)) : T
|
||||
>set : (newU: U) => T
|
||||
>updater(u) : U
|
||||
>updater : (u: U) => U
|
||||
>u : U
|
||||
>set : (newU: U) => T
|
||||
|
||||
};
|
||||
return reduce<T>(t, (t: T) => t);
|
||||
>reduce<T>(t, (t: T) => t) : (<K extends keyof T>(key: K) => (<K extends keyof T[K]>(key: K) => (<K extends keyof T[K][K]>(key: K) => (<K extends keyof T[K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof T[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K][K]) => T[K][K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K][K]) => T[K][K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K][K]) => T[K][K][K][K][K]) => T; set: (newU: T[K][K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K][K]) => T[K][K][K][K]) => T; set: (newU: T[K][K][K][K]) => T; }) & { map: (updater: (u: T[K][K][K]) => T[K][K][K]) => T; set: (newU: T[K][K][K]) => T; }) & { map: (updater: (u: T[K][K]) => T[K][K]) => T; set: (newU: T[K][K]) => T; }) & { map: (updater: (u: T[K]) => T[K]) => T; set: (newU: T[K]) => T; }) & { map: (updater: (u: T) => T) => T; set: (newU: T) => T; }
|
||||
>reduce : <U>(u: U, update: (u: U) => T) => (<K extends keyof U>(key: K) => (<K extends keyof U[K]>(key: K) => (<K extends keyof U[K][K]>(key: K) => (<K extends keyof U[K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K]>(key: K) => (<K extends keyof U[K][K][K][K][K][K][K][K][K][K]>(key: K) => any & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K][K]) => U[K][K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K][K]) => U[K][K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K][K]) => U[K][K][K][K][K]) => T; set: (newU: U[K][K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K][K]) => U[K][K][K][K]) => T; set: (newU: U[K][K][K][K]) => T; }) & { map: (updater: (u: U[K][K][K]) => U[K][K][K]) => T; set: (newU: U[K][K][K]) => T; }) & { map: (updater: (u: U[K][K]) => U[K][K]) => T; set: (newU: U[K][K]) => T; }) & { map: (updater: (u: U[K]) => U[K]) => T; set: (newU: U[K]) => T; }) & { map: (updater: (u: U) => U) => T; set: (newU: U) => T; }
|
||||
>t : T
|
||||
>(t: T) => t : (t: T) => T
|
||||
>t : T
|
||||
>t : T
|
||||
|
||||
};
|
||||
|
||||
// example from https://github.com/microsoft/TypeScript/issues/31605
|
||||
|
||||
export const testRecFun = <T extends Object>(parent: T) => {
|
||||
>testRecFun : <T extends Object>(parent: T) => { result: T; deeper: <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
><T extends Object>(parent: T) => { return { result: parent, deeper: <U extends Object>(child: U) => testRecFun<T & U>({ ...parent, ...child }) };} : <T extends Object>(parent: T) => { result: T; deeper: <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>parent : T
|
||||
|
||||
return {
|
||||
>{ result: parent, deeper: <U extends Object>(child: U) => testRecFun<T & U>({ ...parent, ...child }) } : { result: T; deeper: <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
|
||||
result: parent,
|
||||
>result : T
|
||||
>parent : T
|
||||
|
||||
deeper: <U extends Object>(child: U) =>
|
||||
>deeper : <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
><U extends Object>(child: U) => testRecFun<T & U>({ ...parent, ...child }) : <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>child : U
|
||||
|
||||
testRecFun<T & U>({ ...parent, ...child })
|
||||
>testRecFun<T & U>({ ...parent, ...child }) : { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>testRecFun : <T extends Object>(parent: T) => { result: T; deeper: <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>{ ...parent, ...child } : T & U
|
||||
>parent : T
|
||||
>child : U
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let p1 = testRecFun({ one: '1' })
|
||||
>p1 : { result: { one: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>testRecFun({ one: '1' }) : { result: { one: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>testRecFun : <T extends Object>(parent: T) => { result: T; deeper: <U extends Object>(child: U) => { result: T & U; deeper: <U extends Object>(child: U) => { result: T & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: T & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>{ one: '1' } : { one: string; }
|
||||
>one : string
|
||||
>'1' : "1"
|
||||
|
||||
void p1.result.one;
|
||||
>void p1.result.one : undefined
|
||||
>p1.result.one : string
|
||||
>p1.result : { one: string; }
|
||||
>p1 : { result: { one: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; }
|
||||
>one : string
|
||||
|
||||
let p2 = p1.deeper({ two: '2' })
|
||||
>p2 : { result: { one: string; } & { two: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p1.deeper({ two: '2' }) : { result: { one: string; } & { two: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p1.deeper : <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p1 : { result: { one: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>deeper : <U extends Object>(child: U) => { result: { one: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>{ two: '2' } : { two: string; }
|
||||
>two : string
|
||||
>'2' : "2"
|
||||
|
||||
void p2.result.one;
|
||||
>void p2.result.one : undefined
|
||||
>p2.result.one : string
|
||||
>p2.result : { one: string; } & { two: string; }
|
||||
>p2 : { result: { one: string; } & { two: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; } & { two: string; }
|
||||
>one : string
|
||||
|
||||
void p2.result.two;
|
||||
>void p2.result.two : undefined
|
||||
>p2.result.two : string
|
||||
>p2.result : { one: string; } & { two: string; }
|
||||
>p2 : { result: { one: string; } & { two: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; } & { two: string; }
|
||||
>two : string
|
||||
|
||||
let p3 = p2.deeper({ three: '3' })
|
||||
>p3 : { result: { one: string; } & { two: string; } & { three: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p2.deeper({ three: '3' }) : { result: { one: string; } & { two: string; } & { three: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p2.deeper : <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>p2 : { result: { one: string; } & { two: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>deeper : <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & U & U & U & U & U & U & U & U & U & U & U; deeper: any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>{ three: '3' } : { three: string; }
|
||||
>three : string
|
||||
>'3' : "3"
|
||||
|
||||
void p3.result.one;
|
||||
>void p3.result.one : undefined
|
||||
>p3.result.one : string
|
||||
>p3.result : { one: string; } & { two: string; } & { three: string; }
|
||||
>p3 : { result: { one: string; } & { two: string; } & { three: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; } & { two: string; } & { three: string; }
|
||||
>one : string
|
||||
|
||||
void p3.result.two;
|
||||
>void p3.result.two : undefined
|
||||
>p3.result.two : string
|
||||
>p3.result : { one: string; } & { two: string; } & { three: string; }
|
||||
>p3 : { result: { one: string; } & { two: string; } & { three: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; } & { two: string; } & { three: string; }
|
||||
>two : string
|
||||
|
||||
void p3.result.three;
|
||||
>void p3.result.three : undefined
|
||||
>p3.result.three : string
|
||||
>p3.result : { one: string; } & { two: string; } & { three: string; }
|
||||
>p3 : { result: { one: string; } & { two: string; } & { three: string; }; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => { result: { one: string; } & { two: string; } & { three: string; } & U & U & U & U & U & U & U & U & U & U; deeper: <U extends Object>(child: U) => any; }; }; }; }; }; }; }; }; }; }; }
|
||||
>result : { one: string; } & { two: string; } & { three: string; }
|
||||
>three : string
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
// @declaration: true
|
||||
// @lib: es6
|
||||
|
||||
// Note that both of the following have an `any` in their return type from where we bottom out the type printout
|
||||
// for having too many instances of the same symbol nesting.
|
||||
|
||||
// Slightly simplified repro from https://github.com/microsoft/TypeScript/issues/30732 so it's easier to read and debug
|
||||
export type Key<U> = keyof U;
|
||||
export type Value<K extends Key<U>, U> = U[K];
|
||||
export const updateIfChanged = <T>(t: T) => {
|
||||
const reduce = <U>(u: U, update: (u: U) => T) => {
|
||||
const set = (newU: U) => Object.is(u, newU) ? t : update(newU);
|
||||
return Object.assign(
|
||||
<K extends Key<U>>(key: K) =>
|
||||
reduce<Value<K, U>>(u[key as keyof U] as Value<K, U>, (v: Value<K, U>) => {
|
||||
return update(Object.assign(Array.isArray(u) ? [] : {}, u, { [key]: v }));
|
||||
}),
|
||||
{ map: (updater: (u: U) => U) => set(updater(u)), set });
|
||||
};
|
||||
return reduce<T>(t, (t: T) => t);
|
||||
};
|
||||
|
||||
// example from https://github.com/microsoft/TypeScript/issues/31605
|
||||
|
||||
export const testRecFun = <T extends Object>(parent: T) => {
|
||||
return {
|
||||
result: parent,
|
||||
deeper: <U extends Object>(child: U) =>
|
||||
testRecFun<T & U>({ ...parent, ...child })
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let p1 = testRecFun({ one: '1' })
|
||||
void p1.result.one;
|
||||
let p2 = p1.deeper({ two: '2' })
|
||||
void p2.result.one;
|
||||
void p2.result.two;
|
||||
let p3 = p2.deeper({ three: '3' })
|
||||
void p3.result.one;
|
||||
void p3.result.two;
|
||||
void p3.result.three;
|
||||
Loading…
x
Reference in New Issue
Block a user