diff --git a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts index d6f9f511c7b..daf8e4e63c5 100644 --- a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts +++ b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts @@ -18,3 +18,7 @@ interface Indexed2 { } let ii: { ...Indexed, ...Indexed2, b: boolean, d: number }; let nb: number | boolean = ii[1001]; + +function f(t: T) { + let i: { ...T, [n: number]: string }; +} diff --git a/tests/cases/conformance/types/spread/objectSpreadInference.ts b/tests/cases/conformance/types/spread/objectSpreadInference.ts new file mode 100644 index 00000000000..19841932419 --- /dev/null +++ b/tests/cases/conformance/types/spread/objectSpreadInference.ts @@ -0,0 +1,59 @@ +interface Result { + t: T; + u: U; + v: V; +} +declare function infer(tuv: { ...T, ...U, a: V }): { t: T, u: U, v: V }; +declare function infer2(utv: { ...U, a: V, ...T }): { t: T, u: U, v: V }; +function generic(w: W, x: X, y: Y) { + // should infer { t: {}, u: {}, v: {} } because there is no trailing type parameter + return infer({ ...w, ...x, a: y, b: "different type" }); +} +let b: { b: number }; +let c: { c: number }; +// should infer { t: {}, u: { b: number, c: number }, v: number } +let i1 = infer({ ...b, ...c, a: 12 }); +// should infer { t: { a: number, b: number, c: number }, u: {}, v: {} } +let i2 = infer2({ ...b, ...c, a: 12 }); +// should infer { t: {}, u: {}, v: {} } +let i3 = generic(b, c, { a: 12 }); + +interface Preserved { + kind: 0 | 1 | 2 | 3; +} +class C implements Preserved { + kind: 0 = 0; + a = 1; + method() { return "C"; } +} +declare function revive(t: { ...T }): T; +function genericRevive(u: U) { + let us: { ...U }; + return revive(us); +} +// result should not have `method` +let result = revive({ a: 12, kind: 0 }); +// result2 should be of type C and have `method` +let result2 = revive({ a: 12, kind: 0 }); + +declare function destructureRevive(t: { ...T, a: number }): T; +function genericDestructureRevive(u: U) { + let us: { ...U }; + return destructureRevive(us); +} +// result3 is just `Preserved` because `a` and `method` both get removed +let result3 = destructureRevive({ a: 12, kind: 0 }); +// result4 is still C -- a is not removed -- because we specified the argument explicitly +let result4 = destructureRevive({ a: 12, kind: 0 }); +result4.method(); +result4.a; + +declare function removeIndexSignature(t: { ...T, a: number, [s: string]: number, [n: number]: number }): T; +interface I { + a: number; + b: number; + [s: string]: number; + [n: number]: number; +} +let i: I; +let result5 = removeIndexSignature(i);