interface X { foo(x: number, y: number, ...z: string[]): X; } function foo(x: number, y: number, ...z: string[]) { } var a: string[]; var z: number[]; var obj: X; var xa: X[]; foo(1, 2, "abc"); foo(1, 2, ...a); foo(1, 2, ...a, "abc"); obj.foo(1, 2, "abc"); obj.foo(1, 2, ...a); obj.foo(1, 2, ...a, "abc"); obj.foo(1, 2, ...a).foo(1, 2, "abc"); obj.foo(1, 2, ...a).foo(1, 2, ...a); obj.foo(1, 2, ...a).foo(1, 2, ...a, "abc"); (obj.foo)(1, 2, "abc"); (obj.foo)(1, 2, ...a); (obj.foo)(1, 2, ...a, "abc"); ((obj.foo)(1, 2, ...a).foo)(1, 2, "abc"); ((obj.foo)(1, 2, ...a).foo)(1, 2, ...a); ((obj.foo)(1, 2, ...a).foo)(1, 2, ...a, "abc"); xa[1].foo(1, 2, "abc"); xa[1].foo(1, 2, ...a); xa[1].foo(1, 2, ...a, "abc"); (xa[1].foo)(...[1, 2, "abc"]); class C { constructor(x: number, y: number, ...z: string[]) { this.foo(x, y); this.foo(x, y, ...z); } foo(x: number, y: number, ...z: string[]) { } } class D extends C { constructor() { super(1, 2); super(1, 2, ...a); } foo() { super.foo(1, 2); super.foo(1, 2, ...a); } }