-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Incorrect Recursive Union Emmission #31605
Copy link
Copy link
Closed
Description
TypeScript Version: 3.4.5 & typescript@3.5.0-dev.20190525
Search Terms:
Recursive Emit union
Code
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'})
console.log(p1.result.one)
let p2 = p1.deeper({two: '2'})
console.log(p2.result.one, p2.result.two);
let p3 = p2.deeper({three: '3'})
console.log(p3.result.one, p3.result.two, p3.result.three);Expected behavior:
each depth would produce a unique generic for U
export declare const testRecFun: <T extends Object>(parent: T) => {
result: T;
deeper: <U extends Object>(child: U) => {
result: T & U;
deeper: <Ua extends Object>(child: Ua) => {
result: T & U & Ua;
deeper: <Ub extends Object>(child: Ub) => {
result: T & U & Ua & Ub;
deeper: <Uc extends Object>(child: Uc) => {
result: T & U & Ua & Ub & Uc;
deeper: <Ud extends Object>(child: Ud) => {
result: T & U & Ua & Ub & Uc & Ud;
deeper: <Ue extends Object>(child: Ue) => {
result: T & U & Ua & Ub & Uc & Ud & Ue;
deeper: <Uf extends Object>(child: Uf) => {
result: T & U & Ua & Ub & Uc & Ud & Ue & Uf;
deeper: <Ug extends Object>(child: Ug) => {
result: T & U & Ua & Ub & Uc & Ud & Ue & Uf & Ug;
deeper: <Uh extends Object>(child: Uh) => {
result: T & U & Ua & Ub & Uc & Ud & Ue & Uf & Ug & Uh;
deeper: <Ui extends Object>(child: Ui) => {
result: T & U & Ua & Ub & Uc & Ud & Ue & Uf & Ug & Uh & Ui;
deeper: <Uj extends Object>(child: Uj) => any;
};
};
};
};
};
};
};
};
};
};
};
Actual behavior:
export declare const 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;
};
};
};
};
};
};
};
};
};
};
};
// intermediate steps are lost.
let p1 = testRecFun({one: '1'})
console.log(p1.result.one)
let p2 = p1.deeper({two: '2'})
console.log(p2.result.one, p2.result.two);
let p3 = p2.deeper({three: '3'})
console.log(p3.result.one, p3.result.two, p3.result.three) // error p3.result.two is not ...
Playground Link:
I didn't make this in the playground, but I made a repo for reproduction.
https://github.com/ericwooley/ts-recursive-test
Related Issues:
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScript