Typescript: рдкреНрд░рд╕реНрддрд╛рд╡: рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ -- рднрд┐рдиреНрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рджреЗрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 29 рдЕрдХреНрддреВре░ 2015  ┬╖  265рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: microsoft/TypeScript

рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░

рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рджреЗрдВ

рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рдХрд╛рд░ рджреЗрдиреЗ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрддреЗ рд╣реИрдВред
рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ concat , apply , curry , compose рдФрд░ рд▓рдЧрднрдЧ рдХреЛрдИ рднреА рдбреЗрдХреЛрд░реЗрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИред
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдЗрди рдЙрдЪреНрдЪ-рдХреНрд░рдо рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд╡рд┐рдз рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреА рдЙрдореНрдореАрдж рдХреА рдЬрд╛рддреА рд╣реИред
ES2015 рдФрд░ ES2017 рдорд╛рдирдХреЛрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЙрдкрдпреЛрдЧ рдФрд░ рднреА рд╕рд╛рдорд╛рдиреНрдп рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕рд░рдгрд┐рдпреЛрдВ рдФрд░ рд╡рд╕реНрддреБрдУрдВ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд░реЗрдб рддрд░реНрдХ рдФрд░ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддреЗ рд╣реИрдВред
рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рдЗрди рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдХреЛ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХрд▓, рдмрд╣реБрдд рд╕рд╛рдорд╛рдиреНрдп рдЯрд╛рдЗрдкрд┐рдВрдЧ рд░рдгрдиреАрддрд┐ рдХреЗ рд╕рд╛рде рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рдкреВрд░реА рддрд░рд╣ рдпрд╛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдХрдИ рдореБрджреНрджреЛрдВ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░реЗрдЧрд╛, рдЬрд┐рдирдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

  1. #5331 -- рдЯреБрдкрд▓реНрд╕ рдЖрд░рд╛рдо рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ ...рддрд░реНрдХ
  2. #4130 - рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдХрдВрдкрд╛рдЗрд▓рд░ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░/рдХреЙрд▓ рдЯрд╛рд░рдЧреЗрдЯ рд╕рд┐рдЧреНрдиреЗрдЪрд░ рдорд┐рд╕рдореИрдЪ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИ
  3. #4988 -- Tuples рдХреЛ Array.prototype.slice() рдХреЗ рд╕рд╛рде рдХреНрд▓реЛрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
  4. #1773 -- рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдирд░рд┐рдХ?
  5. #3870 -- рдЪреМрд░рд╛рд╣реЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЗрдирд░рд┐рдХ рдореЗрдВ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░.
  6. #212 -- рдмрд╛рдЗрдВрдб, рдХреЙрд▓ рдФрд░ рдЕрдкреНрд▓рд╛рдИ рдЕрдирдЯрд╛рдЗрдкреНрдб рд╣реИрдВ (#3694 рдХреЗ рдЗрд╕-рдлрдВрдХреНрд╢рди рдЯрд╛рдЗрдк рдХреА рдЬрд░реВрд░рдд рд╣реИ)ред
  7. #1024 -- рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ ... рдЬреЗрдирд░рд┐рдХ рдХреЗ рд╕рд╛рде рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░

рдореИрдВ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ-рд╣реИрдВрдбрдмреБрдХ рдХреЗ рдЕрдкрдиреЗ рдХрд╛рдВрдЯреЗ рдкрд░ рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛: рд╕реИрдВрдбрд░реНрд╕рди/ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ-рд╣реИрдВрдбрдмреБрдХ@76f5a75868de3fb1ad4dbed5db437a8ab61a2698
рдореЗрд░реЗ рдкрд╛рд╕ рд╕реИрдВрдбрд░реНрд╕рди/ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ@f3c327aef22f6251532309ba046874133c32f4c7 рдкрд░ рдПрдХ рдкреНрд░рдЧрддрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд░рд▓ рднрд╛рдЧ рд╣реИрдВред
рдпрд╣ рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рдкреНрд░рд╕реНрддрд╛рд╡ #5296 рдХреЗ рднрд╛рдЧ 2 рдХрд╛ рд╕реНрдерд╛рди рд▓реЗрддрд╛ рд╣реИред
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдкрд░ рдПрдХ рдЕрдиреБрднрд╛рдЧ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ред рдореБрдЭреЗ рдЕрдм рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдЦреНрддреА рд╕реЗ #5296 рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рдЬрд╛рддрд╛ рд╣реИред

curry рд╕рд╛рде рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдЙрджрд╛рд╣рд░рдг

curry рджреЛ рддрд░реНрдХреЛрдВ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ:

function curry(f, a) {
    return b => f(a, b);
}

рдФрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдк рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде:

function curry<T, U, V>(f: (t: T, u: U) => V, a:T): (b:U) => V {
    return b => f(a, b);
}

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдХ рд╡рд┐рд╡рд┐рдз рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

function curry(f, ...a) {
    return ...b => f(...a, ...b);
}

рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ curry рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

function curry<...T,...U,V>(f: (...ts: [...T, ...U]) => V, ...as:...T): (...bs:...U) => V {
    return ...b => f(...a, ...b);
}

рдореИрдВ рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡рд┐рд╡рд┐рдз рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕реНрдкреНрд░реЗрдб рдФрд░ рд░реЗрд╕реНрдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реВрдВред
рдпрд╣ рд╕реАрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрдк рдПрдиреЛрдЯреЗрд╢рди рдХреЛ рд╡реИрд▓реНрдпреВ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рдХрдард┐рди рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕реА рддрд░рд╣, рд╕рдВрдпреЛрдЬрди рдХреЗ рд▓рд┐рдП рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЯрдкрд▓ рдирд┐рд░реНрдорд╛рдг рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдВрдпреЛрдЬрди рд╣реИред

рдЕрдм рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЙрд▓ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ curry :

function f(n: number, m: number, s: string, c: string): [number, number, string, string] {
    return [n,m,s,c];
}
let [n,m,s,c] = curry(f, 1, 2)('foo', 'x');
let [n,m,s,c] = curry(f, 1, 2, 'foo', 'x')();

рдкрд╣рд▓реА рдХреЙрд▓ рдореЗрдВ,

V = [number, number, string, string]
...T = [number, number]
...U = [string, string]

рджреВрд╕рд░реА рдХреЙрд▓ рдореЗрдВ,

V = [number, number, string, string]
...T = [number, number, string, string]
...U = []

рд╡рд╛рдХреНрдп - рд╡рд┐рдиреНрдпрд╛рд╕

рдПрдХ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ ...T рдЬрд╣рд╛рдВ _T_ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ рдЬреЛ рдкрд░рдВрдкрд░рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рдПрдХрд▓ рдЕрдкрд░-рдХреЗрд╕ рдЕрдХреНрд╖рд░ рд╣реИ, рдпрд╛ T рдмрд╛рдж PascalCase рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИред
рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рд╕рдВрджрд░реНрднреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд╛рди рдкрд░ рдмрд╛рдзреНрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдХрдХреНрд╖рд╛рдПрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

function f<...T,...U>() {}
}
class C<...T> {
}

рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдиреЛрдЯреЗрд╢рди рд╕реНрдерд╛рди рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

function makeTuple<...T>(ts:...T): ...T {
    return ts;
}
function f<...T,...U>(ts:...T): [...T,...U] {
    // note that U is constrained to [string,string] in this function
    let us: ...U = makeTuple('hello', 'world');
    return [...ts, ...us];
}

рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░, рдЬреИрд╕реЗ рдкреНрд░рдХрд╛рд░ рдЪрд░, рдХрд╛рдлреА рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╣реИрдВред
рдЯрд╛рдЗрдк рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рдСрдкрд░реЗрд╢рди рд╣реЛрддрд╛ рд╣реИред
рдЙрдиреНрд╣реЗрдВ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдпрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЯреБрдкрд▓реНрд╕ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯрдкрд▓-рд╕реНрдкреНрд░реЗрдбрд┐рдВрдЧ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрдк рдПрдиреЛрдЯреЗрд╢рди рд▓реЛрдХреЗрд╢рди рдореЗрдВ:

let t1: [...T,...U] = [...ts,...uProducer<...U>()];
let t2: [...T,string,string,...U,number] = [...ts,'foo','bar',...uProducer<...U>(),12];

рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╡реЗ рдЬрд╣рд╛рдВ рднреА рдЯрд╛рдЗрдк рдПрдиреЛрдЯреЗрд╢рди рдХреА рдЕрдиреБрдорддрд┐ рджреА рдЧрдИ рдереА, рд╡рд╣рд╛рдВ рджрд┐рдЦрд╛рдИ рджреЗрдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ:

function f<...T>(ts:...T): [...T,string,string] { 
    // note the type of `us` could have been inferred here
    let us: [string,string] = makeTuple('hello', 'world');
    return [...ts, ...us];
}

let tuple: [number, string] = [1,'foo'];
f<[number,string]>(tuple);

рдЕрд░реНрде рд╡рд┐рдЬреНрдЮрд╛рди

рдПрдХ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрд░ рдХрд┐рд╕реА рднреА рд▓рдВрдмрд╛рдИ рдХреЗ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред
рдЪреВрдВрдХрд┐ рдпрд╣ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЯрд╛рдЗрдк рдереНрдпреЛрд░реА рдореЗрдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рдж, рдЗрд╕реЗ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 'рдХрд╛рдЗрдВрдб' рд╢рдмреНрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдХрд┐рд╕реА рднреА рд▓рдВрдмрд╛рдИ рдХреЗ рдЯреБрдкрд▓реНрд╕ рд╣реИ, рд╣рдо 'рддрд░рд╣' рдХреЛ 'рд╡реИрд░рд┐рдПрдбрд┐рдХ' рдХреЗ рд╕рд╛рде рдЕрд░реНрд╣рддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП, рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдЗрд╕реЗ рдХрд┐рд╕реА рднреА _single_ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдкрд░ рд▓реЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдкреНрд░рдХрд╛рд░ рдЪрд░ рдХреА рддрд░рд╣, рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХреЛ рдХреЗрд╡рд▓ рдХрд╛рд░реНрдпреЛрдВ, рдХрдХреНрд╖рд╛рдУрдВ рдЖрджрд┐ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рддрдм рдЙрдиреНрд╣реЗрдВ рд╢рд░реАрд░ рдХреЗ рдЕрдВрджрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

function f<...T>(): ...T {
    let a: ...T;
}

рдПрдХ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдЧрд╛:

f([1,2,"foo"]);

рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдЕрд╕рд╛рдЗрди рдХрд░рддрд╛ рд╣реИ ...T=[number,number,string] ...T . So in this application of f , let a:...T is instantiated as let a:[number,number,string] . However, because the type of a is not known when the function is written, the elements of the tuple cannot be referenced in the body of the function. Only creating a new tuple from a` рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЯрдкрд▓ рдореЗрдВ рдирдП рддрддреНрд╡ рдЬреЛрдбрд╝реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

function cons<H,...Tail>(head: H, tail: ...Tail): [H,...Tail] {
    return [head, ...tail];
}
let l: [number, string, string, boolean]; 
l = cons(1, cons("foo", ["baz", false]));

рдкреНрд░рдХрд╛рд░ рдЪрд░ рдХреА рддрд░рд╣, рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рдЖрдорддреМрд░ рдкрд░ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
cons рдХреЙрд▓ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рдереА:

l = cons<number,[string,string,boolean]>(1, cons<string,[string,boolean]>("foo", ["baz", false]));

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, cons рдХреЛ рджреЛ рдЪрд░, рдПрдХ рдкреНрд░рдХрд╛рд░ _H_ рдФрд░ рдПрдХ рдкреНрд░рдХрд╛рд░ _...Tail_ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЕрдВрддрд░рддрдо рдХреЙрд▓ рдореЗрдВ, cons("foo", ["baz", false]) , H=string рдФрд░ ...Tail=[string,boolean] ред
рд╕рдмрд╕реЗ рдмрд╛рд╣рд░реА рдХреЙрд▓ рдореЗрдВ, H=number рдФрд░ ...Tail=[string, string, boolean] ред
_...Tail_ рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдЯреБрдкрд▓реНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реВрдЪреА рдЕрдХреНрд╖рд░ рдЯрд╛рдЗрдк рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ - рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

let tail: [number, boolean] = ["baz", false];
let l = cons(1, cons("foo", tail));

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрд┐рдд рд╣реЛрдиреЗ рдкрд░ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

function car<H,...Tail>(l: [H, ...Tail]): H {
    let [head, ...tail] = l;
    return head;
}
car([1, "foo", false]);

рдпрд╣рд╛рдВ, l рдХрд╛ рдЕрдиреБрдорд╛рди [number, string, boolean] рд░реВрдк рдореЗрдВ рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдлрд┐рд░ H=number рдФрд░ ...Tail=[string, boolean] ред

рдкреНрд░рдХрд╛рд░ рдЕрдиреБрдорд╛рди рдкрд░ рд╕реАрдорд╛рдПрдВ

рд╕рдорд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЪреЗрдХрд░ рдпрд╣ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рдХреА рд╕реАрдорд╛ рдХрд╣рд╛рдБ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:

function twoKinds<...T,...U>(total: [...T,string,...U]) {
}
twoKinds("an", "ambiguous", "call", "to", "twoKinds")

рдЪреЗрдХрд░ рдпрд╣ рддрдп рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХрд┐ рдЕрд╕рд╛рдЗрди рдХрд░рдирд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ

  1. ...T = [string,string,string], ...U = [string]
  2. ...T = [string,string], ...U = [string,string]
  3. ...T = [string], ...U = [string,string,string]

рдХреБрдЫ рдЕрд╕рдВрджрд┐рдЧреНрдз рдХреЙрд▓ рдЗрд╕ рдкреНрд░рддрд┐рдмрдВрдз рдХреЗ рдХрд╛рд░рдг рд╣реИрдВ:

twoKinds(1, "unambiguous", 12); // but still needs an annotation!

рд╕рдорд╛рдзрд╛рди рдЯрд╛рдЗрдк рдПрдиреЛрдЯреЗрд╢рди рдЬреЛрдбрд╝рдирд╛ рд╣реИ:

twoKinds<[string,string],[string,string]>("an", "ambiguous", "call", "to", "twoKinds");
twoKinds<[number],[number]>(1, "unambiguous", 12);

рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдХреЗ рдмреАрдЪ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ rotate :

function rotate(l:[...T, ...U], n: number): [...U, ...T] {
    let first: ...T = l.slice(0, n);
    let rest: ...U = l.slice(n);
    return [...rest, ...first];
}
rotate<[boolean, boolean, string], [string, number]>([true, true, 'none', 12', 'some'], 3);

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди n рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХреЗ рдмреАрдЪ рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рд╣реИ: рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╣реА рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП n === ...T.length рд╕рд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рд╣реИ рдЬрд┐рд╕реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред

рдХрдХреНрд╖рд╛рдУрдВ рдФрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рд╢рдмреНрджрд╛рд░реНрде

рд╢рдмреНрджрд╛рд░реНрде рдХрдХреНрд╖рд╛рдУрдВ рдФрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рд╕рдорд╛рди рд╣реИрдВред

TODO: рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рд╢рд╛рдпрдж рдХреБрдЫ рд╡рд░реНрдЧ-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЭреБрд░реНрд░рд┐рдпрд╛рдБ рд╣реИрдВред

рдЯреБрдкрд▓реНрд╕ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ

рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрдирдХреЗ рджрд╛рдпрд░реЗ рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рдЖрд░рд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

function apply<...T,U>(ap: (...args:...T) => U, args: ...T): U {
    return ap(...args);
}
function f(a: number, b: string) => string {
    return b + a;
}
apply(f, [1, 'foo']);

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА f: (a: number, b:string) => string рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП instantiated рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдмрдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП ...T ред
рдЕрдиреБрдорд╛рдирд┐рдд рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ [number, string] , рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ (a: number, b: string) => string рдХреЛ (...args: [number, string]) => string рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдлреИрд▓рд╛рдХрд░ рдЗрд╕ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗ, рднрд▓реЗ рд╣реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рди рд╣реЛ:

function g(a: number, ...b: [number, string]) {
    return a + b[0];
}
g(a, ...[12, 'foo']);

рд╡реИрдХрд▓реНрдкрд┐рдХ рдФрд░ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░

рдЪреВрдВрдХрд┐ рдЯреБрдкрд▓реНрд╕ рд╕реАрдзреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдм рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрддреНрдкрдиреНрди рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕рдВрдШ рд╣реЛрддрд╛ рд╣реИред
рдХрд░реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж h рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рджреЗрдЦреЗрдВ:

function curry<...T,...U,V>(cur: (...args:[...T,...U]) => V, ...ts:...T): (...us:...U) => V {
    return ...us => cur(...ts, ...us);
}
function h(a: number, b?:string): number {
}
let curried = curry(h, 12);
curried('foo'); // ok
curried(); // ok

рдпрд╣рд╛рдВ ...T=([number] | [number, string]) , рдЗрд╕рд▓рд┐рдП curried: ...([number] | [number, string]) => number рдЬрд┐рд╕реЗ рдЖрдк рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рд░рдгрдиреАрддрд┐ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдпреЗ рд╕рд┐рд░реНрдл рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВ:

function i(a: number, b?: string, ...c: boolean[]): number {
}
let curried = curry(i, 12);
curried('foo', [true, false]);
curried([true, false]);

рдпрд╣рд╛рдВ, curried: ...([string, boolean[]] | [boolean[]]) => number ред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЯреБрдкрд▓ рд░реЗрд╕реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рдерд╛, рдЬрд╣рд╛рдВ рдЯреБрдкрд▓ рдХрд╛ рдЕрдВрддрд┐рдо рддрддреНрд╡ рдПрдХ рд╕рд░рдгреА рд╣реИред
рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╕рд░рдгреА рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╕рд╛рд░реНрдердХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд▓рдЧрддрд╛ рд╣реИред

рдЯрд╛рдЗрдкрдкреНрд░рддрд┐ рдХреЗ рдЕрдиреНрдп рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░

  1. рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдПрдХ рдЦрд╛рд▓реА рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред
    рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд▓рд┐рдП рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдПрдХ рдЦрд╛рд▓реА рдЯрдкрд▓ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
    рддреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЦрд╛рд▓реА рдЯреБрдкрд▓реНрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рднрд▓реЗ рд╣реА рдХреЗрд╡рд▓ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗред

    рдЙрджрд╛рд╣рд░рдг

рдЗрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрджрд╛рд╣рд░рдг рд╡рд░реНрддрдорд╛рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд-рддрд░реНрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрднрд╡ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╡рд┐рдз рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреБрдЫ, рдЬреИрд╕реЗ cons рдФрд░ concat , рдХреЛ рд╡рд░реНрддрдорд╛рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕рдЬрд╛рддреАрдп рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╖рдо рдЯреБрдкрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрднреНрдпрд╛рд╕ рдХрд╛ рдЕрдзрд┐рдХ рдмрд╛рд░реАрдХреА рд╕реЗ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИред

рдПрдХ рд╕рдВрдпреЛрдЬрд┐рдд рдкреНрд░рдХрд╛рд░ рд▓реМрдЯрд╛рдПрдВ

function cons<H,...T>(head: H, tail:...T): [H, ...T] {
    return [head, ...tail];
}
function concat<...T,...U>(first: ...T, ...second: ...U): [...T, ...U] {
    return [...first, ...second];
}
cons(1, ["foo", false]); // === [1, "foo", false]
concat(['a', true], 1, 'b'); // === ['a', true, 1, 'b']
concat(['a', true]); // === ['a', true, 1, 'b']

let start: [number,number] = [1,2]; // type annotation required here
cons(3, start); // == [3,1,2]

рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдкреНрд░рдХрд╛рд░

function car<H,...T>(l: [H,...T]): H {
    let [head, ...tail] = l;
    return head;
}
function cdr<H,...T>(l: [H,...T]): ...T {
    let [head, ...tail] = l;
    return ...tail;
}

cdr(["foo", 1, 2]); // => [1,2]
car(["foo", 1, 2]); // => "foo"

рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рднрд┐рдиреНрди рдХрд╛рд░реНрдп

function apply<...T,U>(f: (...args:...T) => U, args: ...T): U {
    return f(...args);
}

function f(x: number, y: string) {
}
function g(x: number, y: string, z: string) {
}

apply(f, [1, 'foo']); // ok
apply(f, [1, 'foo', 'bar']); // too many arguments
apply(g, [1, 'foo', 'bar']); // ok
function curry<...T,...U,V>(f: (...args:[...T,...U]) => V, ...ts:...T): (...us: ...U) => V {
    return us => f(...ts, ...us);
}
let h: (...us: [string, string]) = curry(f, 1);
let i: (s: string, t: string) = curry(f, 2);
h('hello', 'world');
function compose<...T,U,V>(f: (u:U) => U, g: (ts:...T) => V): (args: ...T) => V {
    return ...args => f(g(...args));
}
function first(x: number, y: number): string {
}
function second(s: string) {
}
let j: (x: number, y: number) => void = compose(second, first);
j(1, 2);

рдХрд╛рд░реНрдпрд╕реВрдЪреА: рд╕рдХрд╛ f рд╡рд╛рдкрд╕реА ...U рдХреЗ рдмрдЬрд╛рдп U ?

рд╕рдЬреНрдЬрд╛рдХрд╛рд░

function logged<...T,U>(target, name, descriptor: { value: (...T) => U }) {
    let method = descriptor.value;
    descriptor.value = function (...args: ...T): U {
        console.log(args);
        method.apply(this, args);
    }
}

рдкреНрд░рд╢реНрди рдЦреЛрд▓реЗрдВ

  1. рдХреНрдпрд╛ рдЯрдкрд▓-рдЯреВ-рдкреИрд░рд╛рдореАрдЯрд░-рд╕реВрдЪреА рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдпрддрд╛ рдХрд╣рд╛рдиреА рдХрд╛рдпрдо рд╣реИ? рдпрд╣ рд╡реИрдХрд▓реНрдкрд┐рдХ рдФрд░ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЕрд╕реНрдерд┐рд░ рд╣реИред
  2. рдХреНрдпрд╛ рдЕрдиреБрдорд╛рдирд┐рдд рдкреНрд░рдХрд╛рд░ рд╡реИрдХрд▓реНрдкрд┐рдХ-рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдорд▓реЗ рдХреЗ рд╕рд╛рде рдЯреБрдкрд▓реНрд╕ рдХрд╛ рд╕рдВрдШ рд╣реЛрдЧрд╛? рдЪреВрдВрдХрд┐ bind , call рдФрд░ apply рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ bind рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдХреЗ рдмрдЬрд╛рдп рдлрд╝рдВрдХреНрд╢рди-рдирд┐рд░реНрдорд╛рдг рд╕рдордп рдкрд░ рдмрд╛рдзреНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП)ред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЕрдзрд┐рднрд╛рд░ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп рдЙрдирдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЙрдиреНрд╣реЗрдВ рдЕрдзрд┐рднрд╛рд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдВрдШ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╕реАрдзреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдЬреЛ bind et al рдХреЛ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред TODO: рдпрд╣рд╛рдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝реЗрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рд╡рд┐рд╡рд┐рдз рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдирд╣реАрдВ рд╣реИред
  3. рдХреНрдпрд╛ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЙрдирдХреЗ рдЕрдЪреНрдЫреЗ рдХреЙрд▓рд┐рдВрдЧ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖-рдЖрд╡рд░рдг рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рднрд▓реЗ рд╣реА рд╡реЗ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрдВ? (рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ, рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрдкрдиреЗ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд░рдгрд┐рдпреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЙрдирдХреЗ рдкрд╛рд╕ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред)
Fix Available In Discussion Suggestion

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЕрдм TS 4.0 рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд #39094 рджреНрд╡рд╛рд░рд╛ рдареАрдХ рдХрд░ рджреА рдЧрдИ рд╣реИред

рд╕рднреА 265 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

+1, рдпрд╣ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реИ! рдпрд╣ рд╡реИрдХрд▓реНрдкрд┐рдХ рдпрд╛ рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛? рдЕрдзрд┐рдХ рдареЛрд╕, рдХреНрдпрд╛ compose рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рддрд░реНрдХреЛрдВ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?

рдЕрдЪреНрдЫреА рдмрд╛рддред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╡реИрдХрд▓реНрдкрд┐рдХ-рдкрд░рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдЕрдиреБрдордд рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЯреБрдкрд▓ рдХреЗрд╡рд▓ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╣реИрдВ, рдЬреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИред рдореИрдВ рджреЗрдЦреВрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ compose рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рдлрд┐рд░ рдореИрдВ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛ред

рдЕрд╕рд▓ рдореЗрдВ рд╕рдВрдШ рдХреЗ рдкреНрд░рдХрд╛рд░ рд╢рд╛рдпрдж рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рдХреБрдЫ рдЗрд╕ рддрд░рд╣

function f(a: string, b? number, ...c: boolean[]): number;
function id<T>(t: T): T;
let g = compose(f, id): (...ts: ([string] | [string, number] | [string, number, boolean[]]) => number

g("foo"); // ok
g("foo", 12); // ok
g("foo", 12, [true, false, true]); // ok

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдЕрднреА рднреА рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рддреЛрдбрд╝рддрд╛ рд╣реИред

@ahejlsberg , рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рдереЗ рдХрд┐

рддреЛ: +1: рдЗрд╕ рдкрд░ред рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдпрд╣ #3870 рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ (рдФрд░ рдкреВрд░рд╛ рдХрд░реЗрдЧрд╛)ред рд╣рдордиреЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдХ рдХрдВрдкреЛрдЬрд╝ рдЯрд╛рдЗрдк рдПрдкреАрдЖрдИ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдХреБрдЫ рд╕реАрдорд╛рдУрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░рдирд╛ рдкрдбрд╝ рд░рд╣рд╛ рд╣реИред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдЧрд╛!

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрднреА-рдХрднреА рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп "рд╡рд┐рд▓рдп" рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдХреБрдЫ рдЬреИрд╕реЗ рд▓рд┐рдЦреЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

function compose<T, ...U>(base: T, ...mixins: ...U): T&U {
    /* mixin magic */
}

рд╕рд╛рде рд╣реА, рдЖрдкрдХреЗ рдмрд╣реБрдд рд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдЖрдк рдкреНрд░рд┐рдорд┐рдЯрд┐рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд░рд╣реЗ рд╣реИрдВред рдЖрдк рдХреБрдЫ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрд╛рдо рдХреЛ рдХреИрд╕реЗ рджреЗрдЦреЗрдВрдЧреЗ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рд╕рдВрдШрд░реНрд╖ рд╣реИрдВ?

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд░реВрдк рдореЗрдВ #3870 рдпрд╛ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХрдорд╛рддреНрд░ рд░рдЪрдирд╛ рдСрдкрд░реЗрдЯрд░ [T,...U] ред рдЖрдк рдЗрд╕реЗ T + ...U рд░реВрдк рдореЗрдВ рднреА рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ (рдЬреЛ рдХрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЗрд╕рдХрд╛ рдЕрдзрд┐рдХ рд╕рдВрдХреЗрдд рд╣реИ), рд▓реЗрдХрд┐рди #3870 рдФрд░ рдЖрдкрдХреА рдЯрд╛рдЗрдк рдХрдВрдкреЛрдЬрд┐рд╢рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ T & ...U ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдордЭрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ @JsonFreeman рдХреА рдФрд░ @jbondc 'рдкрд╣рд▓реА # 3870 рд╕реЗ рд╡рд┐рдЪрд╛рд░реЛрдВред рдореИрдВ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реВрдВрдЧрд╛ рдпрджрд┐ рдореИрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХреВрдВ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдиреЛрдЯ: рдореИрдВрдиреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ [...T, ...U] рд╕рд╛рде рдЬрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдорд╛рди рдореВрд▓реНрдп рдлреИрд▓рд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди T + ...U рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдЗрд╕рдХрд╛ рдЕрдзрд┐рдХ рд╕рдВрдХреЗрдд рд╣реИред рдпрджрд┐ рд╣рдо рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ + рдФрд░ & рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдСрдкрд░реЗрдЯрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдмрдбрд╝рд╛: +1: рдЗрд╕ рдкрд░!

+1 рдмрдврд╝рд┐рдпрд╛! рдпрд╣ рдРрд╕реА рдЪреАрдЬреЛрдВ рдХреЛ рдЕрдзрд┐рдХ рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рдФрд░ рд╣рд▓реНрдХреЗ рдврдВрдЧ рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

#3870 рдореЗрдВ рдореЗрд░реА рдмрд╛рдд рдпрд╣рд╛рдВ рдПрдХ рдореБрджреНрджрд╛ рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдореИрдВ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рддрд╛ рд╣реВрдВред

рдЯрд╛рдЗрдк рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдПрдХ рдЬрдЯрд┐рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдордп рдХреЗ рд╕рд╛рде рд╕реВрдХреНрд╖реНрдо рддрд░реАрдХреЛрдВ рд╕реЗ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред рдЬрдм рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЦрд┐рд▓рд╛рдл рддрд░реНрдХреЛрдВ рдХрд╛ рдорд┐рд▓рд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрд╕ рдХреНрд░рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рди рд╣реА рдХрд┐рддрдиреЗ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП)ред рдпрд╣ рдЖрдо рддреМрд░ рдкрд░ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд░рд╣реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рдордиреЗ рдЖрдпрд╛ рдкрд░рд┐рдгрд╛рдо (рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ) рдЗрди рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЕрдиреБрдорд╛рди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрджреЗрд╢ рдФрд░ рдЕрдиреБрдорд╛рдиреЛрдВ рдХреА рдЧрд┐рдирддреА рджреЛрдиреЛрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реИред рдЗрди рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рдирд╣реАрдВ рдерд╛ред

рдпрд╣ рдХрд┐рддрдирд╛ рдЧрдВрднреАрд░ рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЕрдиреБрдорд╛рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдХреНрдпрд╛ рд╣реИ:

function f<...T>(x: ...T, y: ...T): ...T { }
f(['hello', 0, true], [[], 'hello', { }]); // what is the type returned by f?

@jbondc , - рдПрдХ рдЕрдЪреНрдЫреЗ рд╡рд┐рдЪрд╛рд░ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреВрдВрдЧрд╛ рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдпрд╣рд╛рдВ рдирд╣реАрдВ рдЦреЛрдЬреВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдкреЗрд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рджреЛрдиреЛрдВ & рдФрд░ + рдирдП рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди & рдПрдХ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддрд╛ рд╣реИ рдЬрдмрдХрд┐ + рдПрдХ рдирдпрд╛ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддрд╛ рд╣реИ (рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореИрдВ рд╕рд┐рдВрдЯреИрдХреНрд╕ [T,...U] рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ) T + ...U , рдХреНрдпреЛрдВрдХрд┐ [T,U] рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ)ред

@JsonFreeman рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рджреЛрд╣рд░рд╛рдП рдЧрдП рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рджреЛ рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд░рдирд╛ рдареАрдХ рд╣реИ:

  1. рд╕рдВрдШ рдХреЗ рдкреНрд░рдХрд╛рд░: f(['hello', 1], [1, false]): [string | number, number | boolean]
  2. рдмрд╛рд░-рдмрд╛рд░ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЕрдиреБрдорд╛рди рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдЯрд╛рдЗрдк рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдЬрдЯрд┐рд▓ рд╕рд╛рдмрд┐рдд рд╣реЛрддрд╛ рд╣реИред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:
f(['hello', 1], [1, false]) // error, type arguments required
f<[string, number]>(['hello', 1], [1, false]) // error, 'number' is not assignable to 'string'
f<[string | number, number | boolean]>(['hello', 1], [1, false]); // ok

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп (рдЬреИрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди @Igorbek рд╕реЗ рдЬреБрдбрд╝реЗ) рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рдХреЗрд╡рд▓ рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдЧрд╛, рднрд▓реЗ рд╣реА рди рддреЛ (1) рдФрд░ рди рд╣реА (2) рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рдпреЛрдЧ рдпреЛрдЧреНрдп рд╣реЛрдВ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЛрдб рдХреЛ рдЬреНрдпрд╛рджрд╛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, curry рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╕рдмрд╕реЗ рдХрдард┐рди рд╣реИ -- рдЖрдкрдХреЛ f: (...args:[...T,...U]) => V рдХреЛ рдЫреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ ...ts:...T , рдлрд┐рд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВ рдФрд░ ...U рдХреЛ рдЬреЛ рд╣реИ рдЙрд╕реЗ рд╕реЗрдЯ рдХрд░реЗрдВ ...T рд╕реЗ f рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЫреЛрдбрд╝ рджрд┐рдпрд╛ред

рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рд╣реИ (sandersn/TypeScript@1d5725d), рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдпрд╣ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред рдХреЛрдИ рд╡рд┐рдЪрд╛рд░ рдЕрдЧрд░ рд╡рд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛?

рдореИрдВ рдРрд╕реА рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рд╣реВрдБ рдЬрд╣рд╛рдБ рд╢рдмреНрджрд╛рд░реНрде рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ (рдЬреИрд╕реЗ рд╕рдорд╛рди рдлреИрд▓реЗ рд╣реБрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдмрд╛рд░-рдмрд╛рд░ рдЕрдиреБрдорд╛рди)ред рдпрд╣ рдореЗрд░реА рдЪрд┐рдВрддрд╛ рдХреЛ рдКрдкрд░ рднреА рджреВрд░ рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдХрд░реА рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреЗ рддрдВрддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪ рд╕рдХрддрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ ...T рддрд░реНрдХ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА рдХреЛ рдЫреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдлрд┐рд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдмрдЪрд╛ рд╣реИред рдпрджрд┐ рдЗрд╕рдХреА рд╕реВрдЪреА рдореЗрдВ рдЕрдВрддрд┐рдо рдирд╣реАрдВ рд╣реИ, рддреЛ рдлреИрд▓реЗ рд╣реБрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдиреАрддрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЧрдиреНрджрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЙрд╕ рдиреЗ рдХрд╣рд╛, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдХреЛрд╢рд┐рд╢ рдХреЗ рдХрд╛рдмрд┐рд▓ рд╣реИред рдЗрд╕ рдлреАрдЪрд░ рдХреА рдХрд╛рдлреА рдбрд┐рдорд╛рдВрдб рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рд╣реА рд╕рдВрджрд░реНрдн рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдХрдИ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╢реАрд░реНрд╖-рд╕реНрддрд░ рдЬреИрд╕реЗ (...T,string,...U) => V рдпрд╛ [...T,...U,...T] рдЬреИрд╕реЗ рд╕рдВрдпреЛрдЬрд┐рдд)ред рдлрд┐рд░ рдЖрдк рдЫреЛрдбрд╝реЗ рдЧрдП рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдПрдХрд╛рдзрд┐рдХ рдкрд╛рд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рд╕реЗ рдЕрдиреБрдорд╛рдирд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рднреА рдЕрд╕реНрдкрд╖реНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдХрд┐рд╕реА рднреА рдмрд┐рдВрджреБ рдкрд░ рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдПрдХ рдкреНрд░рдХрд╛рд░ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ, рддреЛ рд░реЛрдХреЗрдВ рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рд╡рд╛рдкрд╕ рдХрд░реЗрдВред

рдЗрд╕рд▓рд┐рдПред рдЬрдЯрд┐рд▓ред

рдЖрдк рдЗрд╕реА рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдкреНрд░реЗрд░рдгрд╛ рд▓реЗрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреБрдЫ рд╣рдж рддрдХ рдПрдХ рд╕рдВрдШ рдпрд╛ рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╕рдорд╛рди рд╣реИред рдЬрдм рдПрдХ рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдЕрдиреБрдорд╛рди рд╕рдВрджрд░реНрдн рдХрд╛ рд╕рджрд╕реНрдп рд╣реЛрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ function f<T>(x: T | string[]) , рддреЛ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдЯреА рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рдХреА рдЗрдЪреНрдЫрд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИ string[] ред рддреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд╣рд▓реЗ рдЕрдиреНрдп рд╕рднреА рдШрдЯрдХреЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдпрджрд┐ рдХреЛрдИ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЯреА рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдФрд░ рднреА рдХрдард┐рди рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рд╡рд┐рднрд┐рдиреНрди рдЪреМрд░рд╛рд╣реЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рддрд░реНрдХ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛рддрд╛ рд╣реИред

рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдкрдиреЗ рдХреЗрд╡рд▓ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдЕрдВрддрд┐рдо рдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдкрд░ рдЯреБрдкрд▓ рдлреИрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рд╣реИ? рддреЛ [string, ...T] рдХреА рдЕрдиреБрдорддрд┐ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди [...T, string] рдирд╣реАрдВ рд╣реЛрдЧреА?

рдЕрдЧрд░ рдореИрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭреВрдВ, рддреЛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдорд┐рд╢реНрд░рд┐рдд рдХрд╣рд╛рдиреА рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛ред рдХреНрдпрд╛ рдореИрдВ рдЗрд╕ рд╕рдордЭ рдореЗрдВ рд╕рд╣реА рд╣реВрдБ?

рд╢рд╛рдпрджред рдХреНрдпрд╛ рдЖрдк рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗ рд╕рдХрддреЗ рд╣реИрдВ? рдореИрдВ рдорд┐рдХреНрд╕рд┐рди рдкреИрдЯрд░реНрди рдХреЗ рд╕рд╛рде рдзрд╛рд░рд╛рдкреНрд░рд╡рд╛рд╣ рдирд╣реАрдВ рд╣реВрдВред

рдПрдХ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╣реИ ...T рдЬрд╣рд╛рдВ T рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ рдЬреЛ рдкрд░рдВрдкрд░рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рдПрдХрд▓ рдЕрдкрд░-рдХреЗрд╕ рдЕрдХреНрд╖рд░ рд╣реИ, рдпрд╛ T рдЙрд╕рдХреЗ рдмрд╛рдж рдПрдХ PascalCase рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИред

рдХреНрдпрд╛ рд╣рдо рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рдбреЗрд╡рд▓рдкрд░ рдкрд░ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ?

@ рдПрд▓реЗрдХреНрд╕реА-рдмрд╛рдпрдХреЛрд╡ +1ред рдореБрдЭреЗ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рдХрд┐ рдРрд╕рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╣рд╛рд╕реНрдХреЗрд▓ рдкреГрд╖реНрдарднреВрдорд┐ рд╡рд╛рд▓реЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЗрд╕рдХреА рд╕рд░рд╛рд╣рдирд╛ рдХрд░реЗрдВрдЧреЗред

рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдЙрд╕ рд╡рд╛рдХреНрдп рдХреЛ рдЕрд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ 'рдпрд╛' рдХрд╕рдХрд░ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП: "рд╕рдореНрдореЗрд▓рди рджреНрд╡рд╛рд░рд╛ (рдПрдХ рдЕрдкрд░-рдХреЗрд╕ рдЕрдХреНрд╖рд░ || рдЯреА рдПрдХ рдкрд╛рд╕реНрдХрд▓рдХреЗрд╕ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рдмрд╛рдж)"ред рдореИрдВ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдмрд╛рдзрд╛ рдбрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдмрд╕ рд╕рдореНрдореЗрд▓рди рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рдХреНрдпрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, _I_ рдореЗрдВ рд╣рд╛рд╕реНрдХреЗрд▓ рдкреГрд╖реНрдарднреВрдорд┐ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЙрд╕ рднрд╛рд╖рд╛ рдХреЗ рд╕рдореНрдореЗрд▓рдиреЛрдВ рдХреЛ рддреЛрдбрд╝рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВред

рдкрдЯрд░реА рд╕реЗ рдЙрддрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред рдореЗрд░рд╛ рдЖрдЦрд┐рд░реА рдЬрд┐рдЬреНрдЮрд╛рд╕реБ рдкреНрд░рд╢реНрди (рдпрджрд┐ рдЖрдк рдореБрдЭрд╕реЗ рдкреВрдЫрдиреЗ рдореЗрдВ рдХреЛрдИ рдЖрдкрддреНрддрд┐ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ) рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ "рд╕рдореНрдореЗрд▓рди" рдХреНрдпрд╛ рд╣реИ рдЬреЛ рдЯреВрдЯ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреМрди рдЪрд┐рдВрддрд┐рдд рд╣реИ?

@sandersn

рдЗрд╕реЗ T & ...U рдорд╛рдирддреЗ рд╣реБрдП рдЪреЗрдХ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ T & U & V & ... (рдЬреЛ рд╕рд╣рдЬ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ)ред

function assign<T, U, ...V>(obj: T, src: U, ...srcs: ...V): T & U & ...V {
  if (arguments.length < 2) return <T & U & ...V> obj

  for (const key of Object.keys(src)) {
    (<any> obj)[key] = (<any> src)[key]
  }

  if (arguments.length === 2) return <U> obj
  return mixin<T, ...V>(obj, ...srcs)
}

рдпрд╛ рдкрд░рд┐рднрд╛рд╖рд╛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ:

interface Object {
    assign<T, U, ...V>(host: T, arg: U, ...args: ...V): T & U & ...V
}

@ рдПрд▓реЗрдХреНрд╕реА-рдмрд╛рдпрдХреЛрд╡ рдЬрд┐рд╕ рд╕рдореНрдореЗрд▓рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИред рдХреМрди рдЪрд┐рдВрддрд┐рдд рд╣реИ? рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдХреЛ рдирдпрд╛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдкрдврд╝рдирд╛ рд╣реИ, рдЙрдиреНрд╣реЛрдВрдиреЗ рдкрд╣рд▓реЗ рдХрднреА рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИ -- рд╕рдореНрдореЗрд▓рди рдирдП рдкрд╛рдардХреЛрдВ рдХреЛ рдирдП рдХреЛрдб рдХреЛ рддреЗрдЬрд╝реА рд╕реЗ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреЗ рд╣реИрдВред

@sandersn рдХреНрдпрд╛ @ рдПрд▓реЗрдХреНрд╕реА-рдмрд╛рдпрдХреЛрд╡ рдХреЛ рдпрд╣ рдЖрднрд╛рд╕ рд╣реБрдЖ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд _syntactically_ рдЕрдорд╛рдиреНрдп рд╣реЛрдВрдЧреЗ:

function assign<a, b, ...cs>(x: a, y: b, ...zs: ...cs): a & b & ...cs;

@isiahmeadows & рдФрд░ | рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╢реНрди/рднрд╡рд┐рд╖реНрдп рдХреЗ рдХрд╛рдо рдХреЛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрджрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реИред рдЕрднреА рдПрдХрдорд╛рддреНрд░ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдСрдкрд░реЗрдЯрд░ рд╕рдВрдпреЛрдЬрди рд╣реИ: [THead, ...TTail] ред

рдПрдХ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдпреЛрдЬрди рдЕрднреА рднреА рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬрдмрдХрд┐ & рдФрд░ | рдХреНрд░рдорд╢рдГ рдЪреМрд░рд╛рд╣реЗ рдФрд░ рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред

@sandersn рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдореЗрд░рд╛ assign рдЙрджрд╛рд╣рд░рдг рдЗрд╕рдХреЗ рд╕рд╛рде рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛ред

рдпрджреНрдпрдкрд┐:

  1. рдЗрдВрдЯрд░рд╕реЗрдХреНрд╢рди рдХреЙрдиреНрд╕рдЯреЗрдиреЗрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реЛрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХреЙрдиреНрдЯреЗрдиреЗрдЯрд┐рдВрдЧ рд▓рд┐рд╕реНрдЯреНрд╕ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреЙрдиреНрд╕рдЯреЗрдирд┐рдВрдЧ рдбрд┐рдХреНрд╢рдирд░реА рдХреА рддрд░рд╣ рд╣реИред рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рд╡рд╣рд╛рдВ рдореМрдЬреВрджрд╛ рдорд╢реАрдирд░реА рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
  2. рд╕рдВрдШ рдЪреМрд░рд╛рд╣реЗ рдХреА рддрд░рд╣ рд╣реЛрдЧрд╛, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╡рд╣ рдХреЗрд╡рд▓ рд╕рд╛рдорд╛рдиреНрдп рднрд╛рдЧреЛрдВ рдХреЛ рд╣реА рд░рдЦреЗред рдПрдХ рдмрд╛рд░ рдлрд┐рд░, рдореМрдЬреВрджрд╛ рдорд╢реАрдирд░реА рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

@isiahmeadows рдПрдХ рдЪреМрд░рд╛рд╣рд╛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдпреЛрдЬрди рдирд╣реАрдВ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рд╡рд╕реНрддреБ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╕рдВрдШреЛрдВ рдХреЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рдпреВрдирд┐рдпрдиреЗрдВ рднреА рд╡реИрд╕реА рдирд╣реАрдВ рд╣реИрдВ рдЬреИрд╕реЗ рдХреЗрд╡рд▓ рдЧреБрдгреЛрдВ рдХреЛ рд▓реЗрдирд╛ рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рд╕рдорд╛рди рд╣реИред рджреЛрдиреЛрдВ рдореЗрдВ рд░рд╣рдиреЗ рд╡рд╛рд▓реЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рдореВрд╣ рджреНрд╡рд╛рд░рд╛ рдмреЗрд╣рддрд░ рд░реВрдк рд╕реЗ рдЪрд┐рддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

@sandersn рдореИрдВ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рддрд░реНрдХ рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП?

function foo<...T>(...rest: ...T): ...T { }
foo('str', 0, [0]);

рдХреНрдпрд╛ рдкрд░рд┐рдгрд╛рдо [string, number, number[]] ? рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ рдЖрдкрдХреЛ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреЛ рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ рдХреНрд░рдо рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рддрд░реНрдХ рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдПрдХ рдЫреЛрдЯреА рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдкрд╣рд▓реА рдмрд╛рд░ рднреА рд╣реЛрдЧрд╛ рдЬрдм рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорд╛рди рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдкреЗрд╢ рдХрд░реЗрдЧрд╛ред

рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ / рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП ...T рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореЗрд░реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рддреЛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИ:

declare function f<...T>(...a: ...T);

рдЖрдЗрдП рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдореМрдЬреВрджрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВ:

declare function f(...a: number[]);

рдЗрд╕рд▓рд┐рдП рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ a рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ number[] , рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ рд╕рд░рдгреА рд╣реИред рд╕рд╛рджреГрд╢реНрдп рд╕реЗ, рдореИрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ ...T рдПрдХ рд╕рд░рдгреА рдХрд╛ рднреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред
рдЕрдЧрд▓рд╛, рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдо рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

declare function f(...a: [number, string]);
// same as
declare function f(c: number, d: string); // or very close to

рддреЛ рдЕрдм, рд╣рдо рдЕрднреА рднреА рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ a рдХрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рдЯрдкрд▓ рд╣реИ (рдЬреЛ рдПрдХ рд╕рд░рдгреА рд╣реИ)ред

рдореЗрд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡ ...T рдХреА рдзрд╛рд░рдгрд╛ рдХрд╛ рдЗрд▓рд╛рдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рдХреБрдЫ рдЕрдореВрд░реНрдд рдХреНрд░рдордмрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреА рд╕реВрдЪреА" рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╕рдВрдЧрдд рддрд░реАрдХреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдФрд░ рдЗрд╕реЗ рдЙрд╕реА рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЬреИрд╕реЗ рд╣рдо рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

var a: [number, string] = [1, "1"];
var b = [true, ...a]; // this must be [boolean, number, string], but it doesn't work :)

рддреЛ ...a рдЪрд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рд┐рд░реНрдл 1, "1" ред

рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ ...T рдзрд╛рд░рдгрд╛ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░рд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕:

declare function f<...T>(...a: [...T]);
declare function g<H, ...T>(head: H, ...tail: [...T]): [H, ...T];

рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

@Igorbek рдореИрдВ рдЗрд╕ рдзрд╛рд░рдгрд╛ рдкрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ declare function f<...T>(...a: ...T); рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрд░рд╣ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ declare function f(...a: [number, string]); рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рд╣реЛ рд░рд╣рд╛ рд╣реИред

рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ред

рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдореВрд▓ рд░реВрдк рд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕:

function func<...T>(...a: ...T)

рдЕрдЧрд░ рдореИрдВ рдпрд╣ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдБ

function g<...T>(...a: ...T): [number, ...T] { ... }

рддреЛ рдореИрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рдЬрд╛рдКрдВрдЧрд╛:

function f<...T>(...a: ...T): [...T] { return a; }

рддреЛ a рдХрд╛ рдкреНрд░рдХрд╛рд░ [...T] (рд╣рдо рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ), рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдЗрд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ ...T рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИред
рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ ...T рдФрд░ [...T] рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЪрд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдЪрд░ рдХреЗ рд▓рд┐рдП:

var a = [1, 2];
[a] === [[1,2]];
[...a] === [1, 2];
f(...a) === f(1, 2)
...a === 1, 2 // virtually

рдпрджрд┐ рд╣рдо рдорд╛рдирдХ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ

function f(...a: number[]): number[] { return a; }

a рдХрд╛ рдкреНрд░рдХрд╛рд░ number[] (рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛) рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

@isiahmeadows рд╣рд╛рдБ, function f(...a: [number, string]) рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЕрднреА рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдП рд╣реИрдВ рдХрд┐ рд╣рдо рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЗрд▓рд╛рдЬ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рддреЛ, рдЖрдЧреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:

function f<...T, ...U>()
f<[number, string], [boolean, number]>();

рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрддреЗрдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ:

f<...[number, string], ...[boolean, number]>();

рддреЛ рдпрд╣ рднреА рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

function g<T1, T2, T3>()

g<A, B, C>();
// same as
g<...[A, B, C]>();
g<...[A], ...[B, C]>(); 
g<...[A], B, C, ...[]>();

@JsonFreeman рдЗрд╕ рддрд░рд╣ рдореЗрд░рд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХреНрдпреЛрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдореИрдВ рдЯрд╛рдЗрдк рдЕрдиреБрдорд╛рди рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдкреНрд░рд╢реНрди рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдмрд╛рдПрдБ-рд╕реЗ-рджрд╛рдПрдБ рдЕрдиреБрдорд╛рди рдПрдХ _рддреБрдЪреНрдЫ_ рдзрд╛рд░рдгрд╛ рд╣реИ рдмрд▓реНрдХрд┐ рдПрдХ рд╕рд╣реА рд╣реИред рдкрд╣рдЪрд╛рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрддреНрддрд░ рд╣рд╛рдВ рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдРрд╕реЗ рдорд╛рдорд▓реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдЙрддреНрддрд░ рдирд╣реАрдВ рд╣реИред

рдХреНрдпрд╛ рдЖрдк рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдорд╛рди рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреЗ рдПрдХ рдЙрдЬрд╛рдЧрд░ рд╕реЗрдЯ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдореИрдВ рдЕрдиреБрдорд╛рди рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреА рдХрд╛рд░реНрдпрдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд╣реАрдВ рд╕рдордЭрддрд╛, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдореБрдЭреЗ рдпрд╣ рджреЗрдЦрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓реЗрдЧреА рдХрд┐ рдЖрдкрдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИред

рдФрд░ рднреА рдмреЗрд╣рддрд░:

function<...T>(...a: T): T;
// same as
function<...T>(...a: [...T]): T;

рдореИрдВ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░ рдХреЗ рд▓рд┐рдП [] рдЙрдкрд╕рд░реНрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред

function fn<R, []T>(...a:[]T): R;

рдпрд╣ ...T рд╕реЗ рдЫреЛрдЯрд╛ 1 рд╡рд░реНрдг рд╣реИ рдФрд░ (рдореЗрд░реА рд░рд╛рдп рдореЗрдВ) рдХрдо рджреГрд╢реНрдп рд╢реЛрд░ рдХрд░рддрд╛ рд╣реИред

@ рдПрд▓реЗрдХреНрд╕реА-рдмрд╛рдпрдХреЛрд╡ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрд╕ рдкрд░ рд╡рд┐рдкрд░реАрдд рд░рд╛рдп рдХрд╛ рд╣реВрдВред рдпрд╣ рдореМрдЬреВрджрд╛ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рдлрд┐рдЯ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдирдЬрд╝рд░ рд╕реЗ рднреА рдХрдо рд╕реНрдкрд╖реНрдЯ рд╣реИред

[...T] / T рдмрд╛рдХреА рд╕рд░рдгреА рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд▓рдЧрддрд╛ рд╣реИред рдПрдХ рдмрд╛рд░ рдлрд┐рд░, рд╕рд░рдгреА рдФрд░ рдЙрдирдХреЗ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВ:

| рд╕рд░рдгрд┐рдпрд╛рдБ | рдкреНрд░рдХрд╛рд░ (рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ) | рдкреНрд░рдХрд╛рд░ (рдореЗрд░рд╛ рдЕрджреНрдпрддрди) |
| --- | --- | --- |
| var x = [1,2] | рдирд╣реАрдВ | T = [T1, T2] |
| [0, ...x] === [0,1,2] | [T0, ...T] === [T0, T1, T2] | [T0, ...T] === [T0, T1, T2] |
| f(x) === f([1, 2]) | рдирд╣реАрдВ | f<T>() === f<[T1, T2]>() |
| f(...x) === f(1, 2) | f<...T>() === f<[T, T2]> ? | f<...T>() === f<T1, T2> |
| f(0, ...x) === f(1, 2) | f<T0, ...T>() === f<T0, [T, T2]> ? | f<T0, ...T>() === f<T0, T1, T2> |

рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ

function g<...T>(...x: ...T) {
 // being called as g(1, "a");
  var a: ...T; // [number, string] ?
  var b: [number, ...T]; // [number, number, string]
  var c: [...T]; // [number, string] - same as a ? so [...T] is same as ...T - weird
}

рдореЗрд░реЗ рдЕрдкрдбреЗрдЯ рд╕реЗ

function g<...T>(...x: T) {
 // being called as g(1, "a");
  var a: T; // [number, string]
  var b: [number, ...T]; // [number, number, string]
  var c: [...T]; // [number, string]
}

рдЕрджреНрдпрддрди рдЕрдм IMO рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реВрдЪрд┐рдпрд╛рдВ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд▓рдЧрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдЯрд╛рдЗрдк рдХреА рдЧрдИ рд▓рд┐рд╕реНрдкреНрд╕ рднреА рдЗрддрдиреА рджреВрд░ рдирд╣реАрдВ рдЬрд╛рддреА рд╣реИрдВ (рд╕рдорд▓реИрдВрдЧрд┐рдХ рдкреНрд░рдХрд╛рд░, рдХреЛрдИ рднреА?: рдореБрд╕реНрдХрд╛рди :)ред

рдореБрдЭреЗ рдкрд╡рд┐рддреНрд░рддрд╛ рдХрд╛ рдЖрдХрд░реНрд╖рдг рдорд┐рд▓рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдкрд╣рд▓реВ рдХреЛ рднреА рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВред рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рд▓рд╛рдЧреВ рдХрд░рдирд╛ рднреА рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЖрд╕рд╛рди рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╛рдХреА рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдлрд┐рдЯ рдирд╣реАрдВ рдмреИрдарддрд╛ рд╣реИред рдпрд╣ рд▓рдЧрднрдЧ рдЬрд╛рд╡рд╛ (рднрд╛рд╖рд╛) рдпрд╛ рд╕реА рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдореЛрдиреИрдб рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрдИ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА рддрд░рд╣ рд╣реИ - рд╡реЗ рд╣рдореЗрд╢рд╛ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдмрджрд╕реВрд░рдд рдФрд░ рд╣реИрдХрд┐рд╢ рдирд┐рдХрд▓рддреЗ рд╣реИрдВред

@sandersn рдореИрдВ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдХреЗ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдореЗрд░рд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИред рдЯрд╛рдЗрдк рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдлрд┐рд░ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреЛрдИ рдЙрдореНрдореАрджрд╡рд╛рд░ рдЕрдиреНрдп рд╕рднреА рдХрд╛ рд╕реБрдкрд░рдЯрд╛рдЗрдк рд╣реИ, рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╡рд╣ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╡рд┐рдЬреЗрддрд╛ рд╣реИред рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ:

function foo<T>(a: T, b: T): T {}
foo(["hi", 0], ["", ""]);

рддрд░реНрдХреЛрдВ рдХреЛ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдлрд┐рд░ рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рджреЛ рдЙрдореНрдореАрджрд╡рд╛рд░ рдЙрддреНрдкрдиреНрди рд╣реЛрдВрдЧреЗ, рдЕрд░реНрдерд╛рддреН (string | number)[] рдФрд░ string[] ред рд▓реЗрдХрд┐рди рдкрд╣рд▓рд╛ рдЬреАрддреЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рджреВрд╕рд░реЗ рдХрд╛ рд╕реБрдкрд░рдЯрд╛рдЗрдк рд╣реИред рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрднреА рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ string[] рдХрднреА рдЪрд┐рддреНрд░ рдореЗрдВ рдерд╛ред T рд▓рд┐рдП рдПрдХ рдЕрдиреБрдорд╛рди рд╣реИ, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдЙрдореНрдореАрджрд╡рд╛рд░ рдЕрджреГрд╢реНрдп рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рджреЛ рдЪреАрдЬреЗрдВ рдЕрджреГрд╢реНрдп рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдХреНрд░рдо рдФрд░ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рдмрд╣реБрд▓рддрд╛ред

рдпрджрд┐ рдЖрдк ...T рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдП рдЧрдП рдЯрдкрд▓ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╕реВрдЪреА рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдпрд╣рд╛рдВ рдмрд╣реБрд▓рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ:

function foo<...T>(...rest: ...T): ...T
foo(0, 1);

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдЗрд░рд╛рджреЗ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдЯреА рдХреЗ рд▓рд┐рдП [number, number] рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рдЪреЗрдХ рдЗрди рд▓рд╛рдЗрди https://github.com/Microsoft/TypeScript/blob/master/src/compiler/checker.ts#L6256 рдХреЗ рдХрд╛рд░рдг , number рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ T рдХрд╛ рдЕрдиреБрдорд╛рди [number] рд░реВрдк рдореЗрдВ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рд╡рд╣ рдмрд╣реБрд▓рддрд╛ рдореБрджреНрджрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рдерд╛ред

рдЖрджреЗрд╢ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ рд╣реИред рд▓реЗрдХрд┐рди рдХрдИ рдкрд╛рд╕ рд╣реИрдВ, рдФрд░ рддрд░реНрдХреЛрдВ рдХреЛ рдкреБрди: рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдпрджрд┐ рдЙрдирдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред рдпрджрд┐ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рд╡рд╛рд▓реЗ n рддрд░реНрдХ рд╣реИрдВ, рддреЛ рддрд░реНрдХреЛрдВ рдкрд░ n + 1 рдкрд╛рд╕ рд╣реИрдВред рдПрдХ рдЙрджрд╛рд╣рд░рдг Array.prototype.reduce рд╣реИ, рдЬрд╣рд╛рдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡реИрд▓реНрдпреВ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХреЙрд▓рдмреИрдХ рд╕реЗ рдкрд╣рд▓реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдпрд╣ рджрд╛рдИрдВ рдУрд░ рд╣реИред рддреЛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рдХреБрдЫ рдПрдХ рдореБрджреНрджрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

function foo<...T>(...rest: ...T): ...T
foo(x => x, 0);

рд╕рд╣рдЬ рд░реВрдк рд╕реЗ, T [(x: any) => any, number] рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рдЬреЛрдбрд╝реЗ рдЬрд╛рдиреЗ рдХреЗ рдХреНрд░рдо рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ [number, (x: any) => any] ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдк рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдЖрдо рддреМрд░ рдкрд░ рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рдЕрдзреАрди рдХрд╛рд░реНрдп рдЕрдВрдд рддрдХ рд╕реНрдердЧрд┐рдд рдХрд░ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдореИрдВрдиреЗ рдЬрд┐рди рдмрд╣реБрд▓рддрд╛ рдФрд░ рдЖрджреЗрд╢ рдХреЗ рдореБрджреНрджреЛрдВ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рд╣реИ, рд╡реЗ рджреЛрдиреЛрдВ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╕реВрдЪреА рдХреЗ рд╕рд╛рдордиреЗ рдЖрдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред @ahejlsberg рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡реНрдпрдХреНрддрд┐ рд╣реЛрдЧрд╛, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╣ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдХрд╣реА рдЧрдИ рдХрд┐рд╕реА рднреА рдмрд╛рдд рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛, рдкреБрд╖реНрдЯрд┐ рдпрд╛ рдЦрдВрдбрди рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред

@JsonFreeman рдЖрдкрдХреЛ рдХреНрдпреЛрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдореБрджреНрджрд╛ рд╣реЛрдЧрд╛?
рдЗрд╕реЗ рд╡рд╕реНрддреБрддрдГ рдкреНрд░рддреНрдпреЗрдХ рд╢реЗрд╖ рддрдереНрдпрд╛рддреНрдордХ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкреЗрд╢ рдХрд░рдХреЗ рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡рд┐рд░реБрджреНрдз рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдХрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,

function foo<...T>(...rest: T) { ... }
foo(x => x, 0);
// to infer, the following function is used
function foo2<T0, T1>(rest0: T0, rest1: T1) { ... }
foo2(x => x, 0);
// inferred as
foo2<(x: any) => any, number>
// T0 = (x: any) => any
// T1 = number
// T = [T0, T1] = [(x: any) => any, number]

BTW, рдХреНрдпрд╛ рд╣рдо x => x рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ { <T>(x: T): T; } ?

@Igorbek рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдкрдХрд╛ рд╕реБрдЭрд╛рд╡ (рдХрдо рд╕реЗ рдХрдо рдЕрдВрддрд░реНрдЬреНрдЮрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдЗрд╕реЗ рдХрд░рдиреЗ рдХрд╛ рд╕рд╣реА рддрд░реАрдХрд╛ рд╣реИред рдЖрдк T рд▓рд┐рдП рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдореЗрдВ рдПрдХ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдФрд░ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрддреА рд╣реИ (рдпрд╣ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рддрд░реАрдХрд╛ рд╣реИ)ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореЗрд░рд╛ рдХрд╣рдирд╛ рдерд╛, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рдЕрдиреБрдорд╛рди рдЙрдореНрдореАрджрд╡рд╛рд░ рд╕реВрдЪреА рдХреЛ рдЕрдиреБрдорд╛рдирд┐рдд рдЯрдкрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рд╕рд╣реА рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рдпрд╛рдВрддреНрд░рд┐рдХреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

{ <T>(x: T): T; } рдмрд╛рд░реЗ рдореЗрдВ рдЖрдкрдХреА рдмрд╛рдд рдХреЗ рд▓рд┐рдП, рдпрд╣ x => foo(x) рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдирд╣реАрдВ рд╣реИ рдЬрд╣рд╛рдВ foo рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рд╣реИред x рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд▓реЛрдб рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ foo рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ред

рдЯрд╛рдЗрдк-рдЪреЗрдХрд░ рдЕрдиреБрдорд╛рди рдирд┐рдпрдореЛрдВ рдХреЗ рд╕рд╛рде рд▓рдбрд╝рд╛рдИ рд╕реЗ рдПрдХ рдЫреЛрдЯрд╛ рдХрджрдоред
рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЯрд┐рдкреНрдкрдгреА/рд╕реБрдЭрд╛рд╡ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рджреЛ рд╕реБрд╕рдВрдЧрдд рд▓реЗрдХрд┐рди рдкрд░рд╕реНрдкрд░ рдЕрдирдиреНрдп рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ:

1. рдФрдкрдЪрд╛рд░рд┐рдХ рдЖрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ

рдЕрдЧрд░ рд╣рдо рдЗрд╕ рдлреЙрд░реНрдо рдХреЛ рдЪреБрдирддреЗ рд╣реИрдВ:

type F<...Args> = (...args:...Args) => ...Args

рддреЛ рд╣рдореЗрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

var a:  F // a: () => []
var b:  F<number> // b: (arg: number) => [number]
var c:  F<number, string> // c: (arg1: number, arg2: string) => [number, string]
...

рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд┐рд╢реНрд░рд╛рдо рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛ред рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрднрд╛рдЧ рдХреА рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

2. рдЯрдкрд▓ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдмрд╛рдХреА рддрд░реНрдХ

(...args:[string, number]) => boolean    IS EQUIVALENT TO   (s: string, n: number) => boolean

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реНрд▓реЙрдЯ рд╣реЛрддреЗ рд╣реИрдВред

function f<T>(...args: T): T {
    return args;
}

рд╣рдо рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рд╢рд░реНрдд рдкреВрд░реА рд╣реЛрддреА рд╣реИ рддреЛ T рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

  1. T рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреИрд╕реЗ (...args: T) => T
  2. T рдХрд╛ рдЙрдкрдпреЛрдЧ [...T] рдпрд╛ [рд╕рдВрдЦреНрдпрд╛, ...T, рд╕реНрдЯреНрд░рд┐рдВрдЧ] рдЬреИрд╕реА рдкреНрд░рд╕рд╛рд░ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдореЗрдВ рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдПрдХ рджреАрд░реНрдШрд╡реГрддреНрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рд╣рдо рдЗрд╕реЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪреЗрдХрд░ рдХреЗ рднреА _syntactically_ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ)

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдпрд╣ рднреА рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ

function f<T>(...args: [...T]): [...T] {
    return args;
}

рд▓реЗрдХрд┐рди рдпрд╣ рдмреЗрдорд╛рдиреА рд╣реИред

рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдореИрдВ рдмрд╛рдж рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред @JsonFreeman , @sandersn?

@Artazor рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЙрдмрд╛рд▓ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЬрд░реВрд░реА рд╕рдордХрдХреНрд╖ рд╣реИрдВред рджреВрд╕рд░реЗ рдореЗрдВ рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдВрджрд░ рдЖрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдлреИрд▓рд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬрдмрдХрд┐ рдкрд╣рд▓рд╛ рдРрд╕рд╛ рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдХреЗрд╡рд▓ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд╣рд╛рдВ рдФрд░ рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдпрд╣ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рддрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдХреНрд░рдо (рдЯреБрдкрд▓реНрд╕, рд╣рд╕реНрддрд╛рдХреНрд╖рд░, рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрдн) рд▓реЗрддреЗ рд╣реИрдВред

рд╕рд╛рдорд╛рдиреНрдп рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреЗ рд▓рд┐рдП, рдкреНрд░рдХрд╛рд░ рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдХреЗ рдХрд╛рд░рдг рдпрд╣ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдереЗ:

function callback(s: string, n: number): void { }
declare function foo<...T>(cb: (...cbArgs: T) => void, ...args: T): [...T];

foo(callback, "hello", 0, 1);

рдлреВ рдХреНрдпрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ? рдореЗрд░рд╛ рдХрд╣рдирд╛ рдпрд╣ рд╣реИ рдХрд┐ рд▓реЛрдЧ рдЬреЗрдиреЗрд░рд┐рдХ рдирд┐рдпрдореЛрдВ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реЛрдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЕрдзрд┐рдХ рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рддрд░реНрдХ рддрд░реНрдХ рдХреЛ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реАрдХреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЙрди рдорд╛рдорд▓реЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдк рддрд░реНрдХ рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП рдХрдард┐рди рд╣реИрдВ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЗрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рд╡рд┐рдХрд▓реНрдк 1 рдмреЗрд╣рддрд░ рд╣реИред рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рд╣реВрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдХреЗрд╡рд▓ рд╕рд░рдгреА рдкреНрд░рдХрд╛рд░, рдпрд╛ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд▓рдВрдмрд╛рдИ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдореБрдЭреЗ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рднреА рдкрд╕рдВрдж рд╣реИ, рдЬреЛ рдХрд┐ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕рд╛рд░ рдЕрдиреБрдХреНрд░рдо рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рдРрд╕реА рдЪреАрдЬ рд╕реЗ рдЬреБрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдореМрдЬреВрдж рд╣реИред

рдЯреБрдкрд▓реНрд╕ рдкрд░ рдореЗрд░рд╛ рджрд░реНрд╢рди рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ рд╕рд░рдгреА рдорд╛рдиреЛрдВ рдХреЗ рд╕рдмрд╕реЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд▓рдВрдмрд╛рдИ рдЬреНрдЮрд╛рдд рд╣реЛрддреА рд╣реИред рд╡реЗ рд╕рд░рдгреА рдорд╛рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░рдирдЯрд╛рдЗрдо рдЗрдХрд╛рдЗрдпрд╛рдБ рд╣реИрдВред рдореБрдЭреЗ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рд░ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЕрдиреБрдХреНрд░рдо)ред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЖрдкрдХреЛ рдЯреБрдкрд▓ рдореЗрдВ рдЖрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдлреИрд▓рд╛рдиреЗ рдХреА рдЗрдЬрд╛рдЬрдд рд╣реИ, рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдХрд╣рд╛рдиреА рд╣реИред

рдореБрдЭреЗ рдЯреБрдкрд▓ рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд╕рдВрдж рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ рдФрд░ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рднреА рдмрд╣реБрдд рд╕рд╣рдЬ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рдЯреБрдкрд▓ рдХреЛ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдлреИрд▓рд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдЯреБрдкрд▓реНрд╕ рдХреЗрд╡рд▓ рд╕рд░рдгреА рд╣реИрдВ рдФрд░ рдЬрдм рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдореИрдВ рд╕рд░рдгреА рдлреИрд▓рд╛ рд╕рдХрддрд╛ рд╣реВрдВред рддрдм рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛрдб рдХреА рдореЗрд░реА рд╕рдордЭ рд╕реЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рдореЗрд▓ рдЦрд╛рдПрдЧрд╛ред

@JsonFreeman рдЖрдкрдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ foo [string, number, number] рд▓реМрдЯрд╛рдПрдЧрд╛ рдЬреИрд╕рд╛ рдХрд┐ ...args рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЕрдиреБрдорд╛рдирд┐рдд cb рдкреНрд░рдХрд╛рд░ (string, number, number) => void рдФрд░ рдкрд╛рд░рд┐рдд рдХреЙрд▓рдмреИрдХ рдХреЗрд╡рд▓ рдЕрдВрддрд┐рдо рддрд░реНрдХ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдЧрд╛ рдЬреЛ TS рдФрд░ JS рджреЛрдиреЛрдВ рдореЗрдВ рдмрд╣реБрдд рдЖрдо рд╣реИред

рдореБрдЭреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рд░ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдбрд┐рд╡рд╛рдЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ

рдареАрдХ рдпрд╣реА рд╡реЗ рд╣реИрдВ, рдЬреЗрдПрд╕ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирддрд╛, рдХреЗрд╡рд▓ рдЯреАрдПрд╕ред TS рдХреЗ рд▓рд┐рдП рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдХреНрд░рдо рд╣реИред

рдореБрдЭреЗ рдЯреБрдкрд▓-рдЖрдзрд╛рд░рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рднреА рдкрд╕рдВрдж рд╣реИред рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдВрдЧрдд рдХрд╛рд░реНрдп рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ:

// all are equivalent
(a: A, b: B, c: C) => R;
(a: A, b: B, ...rest: [C]) => R;
(a: A, ...rest: [B, C]) => R;
(...args: [A, B, C]) => R;

// this is more complicated 
(a: A, ...rest: T[]) => R;
(...args: [A, ...T]) => R; // no in current syntax

рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рд╣рдо рд╡рд░реНрддрдорд╛рди рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рд╡реНрдпрдХреНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо #6229 рдХреЛ рдЕрдкрдирд╛рдпрд╛ рд╣реЛрддрд╛ред
рддреЛ рдореЗрд░реЗ рд▓рд┐рдП рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдзрд┐рдХ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреБрдкрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдирд╛ рдПрдХ рдЙрдЪрд┐рдд рддрд░реАрдХрд╛ рд╣реИред рдЕрдзрд┐рдХ рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдмрд┐рдирд╛, [...T, ...T] рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реЛрдирд╛ рдХрдард┐рди рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ T рдПрдХ рдЯреБрдкрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЦреБрд▓реА рд▓рдВрдмрд╛рдИ рд╣реИред

@JsonFreeman рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, @Pajn рдиреЗ рдмрд┐рд▓реНрдХреБрд▓ рдореЗрд░реА рд╕рдордЭ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ - рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛

@JsonFreeman рдореИрдВ рдЙрд╕ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдмреЗрд╣рддрд░ рдЙрдкрдпреЛрдЧ

declare function foo<T>(cb: (...cbArgs: T) => void, ...args: T): T;
declare function foo<T>(cb: (...cbArgs: T) => void, ...args: T): [...T]; // same

рд╣рдореНрдо, рд╢рд╛рдпрдж рдпрд╣ рдХреБрдЫ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдкреЗрд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

declare function foo<T>(...args: T): T;
foo(1); // T is [number] or number[]?

// however, here it'd be more explicit
declare function foo<T>(...args: T[]): T[];
foo(1); // T is number[]

// and here
declare function foo<T>(...args: [...T]): T;
foo(1); // T is [number]

рдореИрдВ рдПрдХ рдЯреБрдкрд▓ рдореЗрдВ рдЖрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдлреИрд▓рд╛рдиреЗ рдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреЗ рдкреАрдЫреЗ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рдЯреБрдкрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред @Pajn рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдЕрднреА рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдкрджреЛрдВ (рдЯреБрдкрд▓реНрд╕, рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА, рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ) рдореЗрдВ рдлреИрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред

@Igorbek рдЖрдк рдЕрдкрдиреЗ рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд╣реА рд╣реИрдВред рдЖрдкрдХрд╛ рддреАрд╕рд░рд╛ рдЙрджрд╛рд╣рд░рдг рднреА рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реИред number, string рдЬреИрд╕реЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ 2 рд╕рдВрднрд╛рд╡рд┐рдд рддрддреНрдХрд╛рд▓рддрд╛рдПрдВ рд╣реИрдВред рдЕрд░реНрдерд╛рддреН (arg1: number, arg2: string) => [number, string] рдФрд░ рд╕рд╛рде рд╣реА (arg1: [number, string]) => [number, string] (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рд╣рд┐рдд рдЯрдкрд▓ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЛ рдЕрдкрдирд╛рдирд╛)ред

рдирд┐рд╣рд┐рдд рдЯрдкрд▓ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реА рдЕрдЬреАрдм рдмрд╛рдд рдпрд╣ рд╣реИ: рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ T рд╣реИ рдЬрд┐рд╕реЗ number, string рддрддреНрдХрд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдЕрдм рдХрд╣реЗрдВ рдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, Foo<T> ред рдХреНрдпрд╛ рдЗрд╕рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ Foo<[number, string]> рд░реВрдк рдореЗрдВ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдЬрдмрдХрд┐ Foo<...T> Foo<number, string> ? рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЛ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рддрдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдореИрдВ рдЕрднреА рднреА рдЯрдкрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ Foo<[...T]> рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ

рдореБрдЭреЗ рдкрд╛рдЧрд▓ рдХрд╣реЛ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдореВрд▓рднреВрдд рдЦрд╛рдорд┐рдпрд╛рдВ рдорд╣рд╕реВрд╕ рд╣реЛрддреА рд╣реИрдВ
рдЯреБрдкрд▓реНрд╕ рдпрджрд┐ рдЖрдк рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореЗрдВ рдлреИрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ
рдкреИрд░рд╛рдореАрдЯрд░? рдЗрд╕ рдХрджрд░?

declare function foo<T>(...args: [...T]): void
foo<[number]>(1, 2)

рд╕рд╛рде рд╣реА, рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдпрджрд┐ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ рдпрд╛ рдЗрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рдЕрд╕рд╛рдорд╛рдиреНрдп, рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЧрд▓рдд рд╕реНрдерд╛рди?

// 1. unusual place
declare foo<T>(x: T, ...ys: [...T]): void

// 2. bad type
declare foo<T>(...xs: [...T]): void
foo<number>(2)

рдкрд╣рд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдлрд╝рдВрдХреНрд╢рди#рд▓рд╛рдЧреВ рдХреЗ рд▓рд┐рдП рд╕реАрдзреЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ (рдФрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ a
рддреНрд░реБрдЯрд┐), рдФрд░ рджреВрд╕рд░реА рдПрдХ рдЧреИрд░-рд╕реНрдкрд╖реНрдЯ рдЧрд▓рддреА рд╣реИ рдЬреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧреА,
рдФрд░ Intellisense рдХреЗ рд╕рд╛рде рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреИрд░-рддреБрдЪреНрдЫред

рд╕реВрд░реНрдп рдкрд░, реирео рдлрд░рд╡рд░реА реирежрезрем, режрей:режрек рдЬреЗрд╕рди рдлреНрд░реАрдореИрди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

рдирд┐рд╣рд┐рдд рдЯрдкрд▓ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реА рдЕрдЬреАрдм рдмрд╛рдд рдпрд╣ рд╣реИ: рдХрд╣рддреЗ рд╣реИрдВ
рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЯреА рд╣реИ рдЬрд┐рд╕реЗ рд╕рдВрдЦреНрдпрд╛, рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рддрддреНрдХрд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
рдЕрдм рдХрд╣реЗрдВ рдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдлреВ. рдХреНрдпрд╛ рдпрд╣ рд╣реЛрдирд╛ рд╣реИ
рдлреВ<[рд╕рдВрдЦреНрдпрд╛, рд╕реНрдЯреНрд░рд┐рдВрдЧ]> рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЧрдИ рдЬрдмрдХрд┐ рдлреВ<... рдЯреА> рдлреВ рд╣реИ рд╕реНрдЯреНрд░рд┐рдВрдЧ>?

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -189817561
.

@JsonFreeman

рдЖрдкрдХрд╛ рддреАрд╕рд░рд╛ рдЙрджрд╛рд╣рд░рдг рднреА рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реИред number, string рдЬреИрд╕реЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ 2 рд╕рдВрднрд╛рд╡рд┐рдд рддрддреНрдХрд╛рд▓рддрд╛рдПрдВ рд╣реИрдВред рдЕрд░реНрдерд╛рддреН (arg1: number, arg2: string) => [number, string] рдФрд░ рд╕рд╛рде рд╣реА (arg1: [number, string]) => [number, string] (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рд╣рд┐рдд рдЯрдкрд▓ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЛ рдЕрдкрдирд╛рдирд╛)ред

рдореЗрд░реЗ рддреАрд╕рд░реЗ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ (...args: [number, string]) => [number, string] рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

declare function foo<T>(...args: [...T]): T;
foo(1, "a"); // T is [number, string]
const result: [number, string] = foo<[number, string]>(1, "a");

// however, it is assignable to/from the following signatures:
const f1: (arg1: number, arg2: string) => [number, string] = foo<[number, string]>;
const f2: (arg1: number, ...rest: [string]) => [number, string] = foo<[number, string]>;

рдирд┐рд╣рд┐рдд рдЯрдкрд▓ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реА рдЕрдЬреАрдм рдмрд╛рдд рдпрд╣ рд╣реИ: рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ T рдХреЛ рддрддреНрдХрд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ number, string ред

T рдХреЛ number, string рддрддреНрдХрд╛рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЯрдкрд▓ рд╣реИред рдпрд╣ [number, string] рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЕрдм рдХрд╣реЗрдВ рдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, Foo<T> ред рдХреНрдпрд╛ рдЗрд╕рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ Foo<[number, string]> рд░реВрдк рдореЗрдВ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдЬрдмрдХрд┐ Foo<...T> Foo<number, string> ?

рд╕рддреНрдпред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП <...T> рдмреЗрдорд╛рдиреА рд▓рдЧрддрд╛ рд╣реИ (рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рддрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрдХрдбрд╝реЗрдВ)ред рдлрд┐рд░ рднреА, рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИред

рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЛ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рддрдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдореИрдВ рдЕрднреА рднреА рдЯрдкрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ Foo<[...T]> рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ

рдРрд╕реЗ рджреЛ рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрдм рд╣рдо рдЙрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

// in a signature declaration
declare function foo<[...T]>(...args: [...T]): [...T];
// and when type instantiated, so in the usage
type T = [number, string]
foo<T>();
foo<[...T]>();
// the latter can virtually be replaced as
type _T = [...T]; // which is a type operation that should produce [number, string]
foo<_T>();
// and more
type Extended = [boolean, ...T]; // [boolean, number, string]

рддреЛ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдпрд╣ | , & рдпрд╛ [] рдЬреИрд╕реЗ рдЯрд╛рдЗрдк рдСрдкрд░реЗрдЯрд░ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдШреЛрд╖рдгрд╛ рдореЗрдВ рдХрд┐ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ T extends any[] рд░реВрдк рдореЗрдВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдпрд╛ рд╕рднреА рдЯреБрдкрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рдЬреЛ рднреА рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдПрдХ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

@isiahmeadows

рдпрджрд┐ рдЖрдк рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореЗрдВ рдлреИрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ
рдкреИрд░рд╛рдореАрдЯрд░? рдЗрд╕ рдХрджрд░?

declare function foo<T>(...args: [...T]): void
foo<[number]>(1, 2); // ok, foo<[number]> is of type (...args: [number]) => void
// [1, 2] is being passed in place of args
// is [1, 2] which is [number, number] assignable to [number]? yes, with current rules
// no error

рд╕рд╛рде рд╣реА, рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдпрджрд┐ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ рдпрд╛ рдЗрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рдЕрд╕рд╛рдорд╛рдиреНрдп, рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЧрд▓рдд рд╕реНрдерд╛рди?

// 1. unusual place
declare foo<T>(x: T, ...ys: [...T]): void
// 1. [...T] can be interpret as a type constraint "must be a tuple type"
// 2. if we call with type specified
foo<number>(1); // number doesn't meet constraint
foo<[number]>(1, 2); // argument of type 'number' is not assignable to parameter 'x' of type '[number]'
foo<[number]>([1], 2); // ok
// 3. if we call without type, it must be inferred
foo(1); // according to current rules, T would be inferred as '{}[]' - base type of all tuples
        // so, argument of type 'number' is not assignable to parameter 'x' of type '{}[]'
foo([1, 2], 2); // T is inferred as '[number, number]
                // rest arguments of type '[number]' are not assignable to rest parameters 'ys' of type '[number, string]'
foo([1], 2, 3); // T is '[number]',
                // x is of type '[number]',
                // ys is of type '[number]',
                // rest arguments are of type '[number, number]' which is assignable to '[number]',
                // no error

// 2. bad type
declare foo<T>(...xs: [...T]): void
foo<number>(2); // type 'number' doesn't meet constraint

рдореБрдЭреЗ рдЕрднреА рднреА рдЗрди рдЪреАрдЬреЛрдВ рдХреЛ рдЯреБрдкрд▓реНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рд▓рд╛рдн рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ <...T> рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рди рдХрд┐ <T> ред рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХрд╣рд╛ рдерд╛, рдореИрдВ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдордирдорд╛рдиреА рд▓рдВрдмрд╛рдИ рдкреНрд░рдХрд╛рд░ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рд╣реВрдВред рдореБрдЭреЗ рдЕрднреА рднреА рдпрдХреАрди рдирд╣реАрдВ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдХрд┐ рд▓реЛрдЧреЛрдВ рдХреЛ рдЬреЛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЪрд╛рд╣рд┐рдП, рдЙрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдпрд╣ рдЕрдзрд┐рдХ рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдерд┐рддрд┐ рдореЗрдВ 'рд╕реНрдкреНрд░реЗрдб' рдСрдкрд░реЗрдЯрд░ рд╣реЛрдиреЗ рд╕реЗ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реАрдорд┐рдд рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ, рдЬреИрд╕реЗ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдмрд╛рд░ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рддреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ <...T> рдФрд░ <A, B, C> , T рдЙрдиреНрд╣реЗрдВ [A, B, C] рд░реВрдк рдореЗрдВ рдкрдХрдбрд╝ рд▓реЗрдЧрд╛ред рдФрд░ рд╣рдо <...T, ...U> рдХреЛ рд╡реНрдпрдХреНрдд рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реЛрдЧрд╛ - [A, B, C], [] рдпрд╛ [A, B], [C] рдпрд╛ ... рдЖрджрд┐ред

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╛рд░реЛрд╣ рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛:

declare function foo(a: A, b: B): R;
declare function boo(c: C, d: D, e: E): U;

let combined: (a: A, b: B, c: C, d: D, e: E) => [R, U] = combine(foo, boo);

// so the signature could be:

declare function combine<R, U, ???>(
  f1: (...args: [...T1]) => R,
  f2: (...args: [...T2]) => U):
    (...args: [...T1, ...T2]) => [R, U];

// if ??? is '...T1, ...T2'
combine<R, U, A, B, C, D, E> // what will be T1 and T2 ?
combine<R, U, ...[A, B, C], ...[D, E]> // ok ? so we will preserve spread to specific positions. so then
combine<...[R, U], A, ...[B, C, D], E> // will be restricted.
// however, ES6 allows to do it with function arguments
f(1, 2, 3);
f(...[1, 2], 3);
f(...[1], ...[2, 3]);

// if ??? is 'T1 extends TupleBase, T2 extends TupleBase'
// or just '[...T1], [...T2]' as a shortcut for such constraints
combine<R, U, [A, B, C], [D, E]> // pretty explicit, and doesn't occupy spread operator for type arguments

рдареАрдХ рд╣реИ, рдЕрдм рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ рд╕реЛрдЪ рд░рд╣реЗ рд╣реИрдВред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЬреЛ рдкреНрд░рд╕реНрддрд╛рд╡ рджреЗ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрд░реЗ рд╡рд┐рдЪрд╛рд░ рд╕реЗ рдПрдХ рдЕрд▓рдЧ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИред рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдирд┐рд░реНрдорд╛рдг рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдХреЗрд╡рд▓ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдлреИрд▓рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣, рдЕрдзрд┐рдХ рдкрд╛рд░рджрд░реНрд╢реА рддрд░реАрдХреЗ рд╕реЗ рд╡рд┐рднрд┐рдиреНрди рд▓рдВрдмрд╛рдИ рдХреЗ рдХрдИ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдпрд╣ рдЕрдзрд┐рдХ рдХреА рддрд░рд╣ рд╣реИ function foo([...rest]) { } рдХреЗ рдмрдЬрд╛рдп function foo(...rest) { } ред

рдпрд╣ рдЕрдм рдореБрдЭреЗ рдФрд░ рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдЪрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИред

@JsonFreeman рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА!

@JsonFreeman рдкреНрд░рд╢реНрди: [1, 2] рдХреЛ [number] рд╕рдВрддреБрд╖реНрдЯ рдХреНрдпреЛрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП? рдпрд╣ рдореБрдЭреЗ рдмрд╣реБрдд рдЕрдЬреАрдм рд▓рдЧрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╣реЛрдЧрд╛ред рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИред

рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдЦрд┐рд▓рд╛рдл рдХреБрдЫ рднреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ (рдореИрдВ рддрдЯрд╕реНрде рд╣реВрдВ, рдИрдорд╛рдирджрд╛рд░ рднреА рд╣реВрдВ)ред

@isiahmeadows рдХрд┐рд╕ рддрд░рд╣ рд╕реЗ [1, 2] [number] рд▓рд┐рдП рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ? рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реИред рдпрд╣ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕реЗ { x: 1, y: 2 } рдПрдХ рд╡реИрдз { x: number }

рдареАрдХред рдореИрдВ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди Function.prototype.apply рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддрд╛ рд╣реВрдВ, рдЬреЛ рддрд░реНрдХреЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред

interface Function<T, U, V> {
    (this: T...args: [...U]): V;
    apply(object: T, args: U): V;
}

рдпрджрд┐ рдХреЙрд▓рд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рддрд░реНрдХреЛрдВ рдкрд░ рдПрдХ TypeError рдлреЗрдВрдХрддрд╛ рд╣реИ, рддреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкрд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреА, рди рдХрд┐ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рдЬреИрд╕реЗ рдХрд┐ рдЗрд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХреНрдпрд╛ рдХрд┐рд╕реА JS рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдкрд░ TypeError рдХреЛ рдлреЗрдВрдХрдирд╛ рдмрд╣реБрдд рджреБрд░реНрд▓рдн рдирд╣реАрдВ рд╣реИ? рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рдХреНрдпрд╛ рд╣реИрдВ?

@isiahmeadows рдПрдХ рдЕрдореВрд░реНрдд рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рд╕рдордЭ рдЧрдпрд╛ рдХрд┐ рдЬрд┐рд╕ рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдЪрд┐рдВрддрд┐рдд рд╣реИрдВ рд╡рд╣ рд╣реИ:

function f(x: number): void {
  // throw if too many arguments
}
f.apply(undefined, [1,2,3]); // runtime error, no compile-time error
f(1,2,3) // compile-time error and runtime error.

рдХреНрдпрд╛ рд╡реЛ рд╕рд╣реА рд╣реИ?

@sandersn , рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕реЗ рддрд░реНрдХреЛрдВ рдкрд░ TypeError рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдЬреЗрдПрд╕ рдХреА рднрд╛рд╡рдирд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЖрдо рддреМрд░ рдкрд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓реЛрдЧреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдо рдФрдкрдЪрд╛рд░рд┐рдХ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдмрд╕ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП Array.prototype.forEach

рдлрдВрдХреНрд╢рди рдХрд░реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рд░рд╛рдорджрд╛рд╕ рдХреЗ рд╕рд╛рде рдпрд╣ рд╢рд╛рдпрдж рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ
рдФрд░ рд▓реЙрд╢/fp.

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ резрей:рекрел рдЕрдирд╛рддреЛрд▓реА рд░реЗрд╕рд┐рди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

@sandersn https://github.com/sandersn , рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ TypeError рднреА
рдХрдИ рддрд░реНрдХ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдЬреЗрдПрд╕ рдХреА рднрд╛рд╡рдирд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо
рдЖрдо рддреМрд░ рдкрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддрд░реНрдХреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдо рдФрдкрдЪрд╛рд░рд┐рдХ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ
рдЗрд╕ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИред рд╣рдо рдмрд╕ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
Array.prototype.forEach

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190327066
.

@isiahmeadows рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ arguments.length рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдХрд░реА рдмрд╣реБрдд рдЕрд╕реНрдерд┐рд░ рдФрд░ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐-рдкреНрд░рд╡рдг рд╣реИред рдЕрд╕рд▓реА рдХрд░реА рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ-рд╕рдмреВрдд рд╣реИ:

var plus = x => y => x + y
console.log(plus(3)(4)) // 7
console.log(plus(3,10)(4,20)) // still 7

рдЬрдм рдореИрдВ рдЕрдкрдиреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рд╢реНрдЪрд┐рдд рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд╕рд╛рде рдХрд╣реАрдВ рдкрд░ рдХреЙрд▓рдмреИрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рд╕реЛрдЪрддрд╛ рд╣реВрдВ: 'рдореЗрд░рд╛ рдХрд╛рд░реНрдп _at рдХрдо рд╕реЗ рдХрдо_ рдЙрди рддрд░реНрдХреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ'

foldl рдЬреИрд╕реА рдЪреАрдЬрд╝реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

const list = [1, 2, 3]
console.log(foldl((a, b) => a + b, 0, list))
console.log(foldl((a, b) => a + b, 0)(list))
console.log(foldl((a, b) => a + b)(0, list))
console.log(foldl((a, b) => a + b)(0)(list))

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рдЖрдо рд╣реИред рдФрд░ рдЖрдЦрд┐рд░реА рдХреЛ рдЫреЛрдбрд╝рдХрд░
рддрд░реНрдХ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИред

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ, резрей:релреи рдЕрдирд╛рддреЛрд▓реА рд░рд╛рд▓ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

@isiahmeadows https://github.com/isiahmeadows рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдХрд░реАрдВрдЧ
aruments.length рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрд╣реБрдд рдЕрд╕реНрдерд┐рд░ рдФрд░ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐-рдкреНрд░рд╡рдг рд╣реИред
рдЕрд╕рд▓реА рдХрд░реА рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ-рд╕рдмреВрдд рд╣реИ:

рд╡рд░ рдкреНрд▓рд╕ = x => y => x + y
рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ(рдкреНрд▓рд╕(3)(4)) // 7
рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ(рдкреНрд▓рд╕(3,10)(4,20)) // рдЕрднреА рднреА 7

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment-190330620
.

рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХреЙрд▓рдмреИрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдХрд╣реЗрдВ, map (рдПрдХ рд╕реВрдЪреА рдкрд░ рдХрд╛рдо рдХрд░рдирд╛
рд╕реВрдЪрд┐рдпреЛрдВ рдХрд╛), рдЖрдк рд╢рд╛рдпрдж рдЗрд╕реЗ рдХрд░реА рдмрдирд╛рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ, резрей :релреп [email protected] рдиреЗ рд▓рд┐рдЦрд╛:

foldl рдЬреИрд╕реА рдЪреАрдЬрд╝реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

const list = [1, 2, 3]
console.log(foldl((a, b) => a + b, 0, list))
console.log(foldl((a, b) => a + b, 0)(list))
console.log(foldl((a, b) => a + b)(0, list))
console.log(foldl((a, b) => a + b)(0)(list))

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рдЖрдо рд╣реИред рдФрд░ рдЖрдЦрд┐рд░реА рдХреЛ рдЫреЛрдбрд╝рдХрд░
рддрд░реНрдХ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИред

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ, резрей:релреи рдЕрдирд╛рддреЛрд▓реА рд░реЗрдЬрд┐рди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com
рд▓рд┐рдЦрд╛ рдерд╛:

@isiahmeadows https://github.com/isiahmeadows рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдХрд░реАрдВрдЧ
aruments.length рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрд╣реБрдд рдЕрд╕реНрдерд┐рд░ рдФрд░ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐-рдкреНрд░рд╡рдг рд╣реИред
рдЕрд╕рд▓реА рдХрд░реА рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ-рд╕рдмреВрдд рд╣реИ:

рд╡рд░ рдкреНрд▓рд╕ = x => y => x + y
рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ(рдкреНрд▓рд╕(3)(4)) // 7
рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ(рдкреНрд▓рд╕(3,10)(4,20)) // рдЕрднреА рднреА 7

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment-190330620
.

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬреНрдпрд╛рджрд╛рддрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ:

type T = [number, string];
var a: T = [1, "a", 2]; // valid

// in this cases tuple types or parameter types cannot be inferred:
f(...a, true); // you could think number,string,boolean were passed, but weren't
const c = [...a, true]; // you could think that is of type [number, string, boolean] but it's not
// according to current rules, the best inferred types might be [number, string, number|string|boolean]

// same manner with variadic kinds, types are constructed properly:
type R = [...T, boolean]; // [number, string, boolean]

рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ #6229 . рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рд╣реИ

рдпрд╣ рдкреНрд░рд╢реНрди рдХрд┐ рдХреНрдпрд╛ [1, 2] [number] рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдкреВрдЫрдиреЗ рдФрд░ рдмрд╣рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдз рдкреНрд░рд╢реНрди рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╕реНрдкреНрд░реЗрдбреЗрдмрд▓ рдЯреБрдкрд▓реНрд╕ рдлреАрдЪрд░ рд╕реЗ рдХреНрдпрд╛ рд▓реЗрдирд╛-рджреЗрдирд╛ рд╣реИ?

рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдПрдХ рд╡рд┐рд╡рд┐рдз рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рдпрд╛ рдирд╣реАрдВред рдпрд╣ рдЕрддрд┐рднрд╛рд░рд┐рдд рдХрд╛рд░реНрдп рдореЗрд░реА рдЪрд┐рдВрддрд╛ рдХрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

declare function foo(x: number, ...args: string[]): void
declare function foo<T>(...args: [...T]): void
foo<[number]>(1, 2)

// This will always fail
declare function foo(x: number, ...args: string[]): void
declare function foo<T>(x: T): void
foo<number>(1, 2)

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ, резрео:рекрен рдЬреЗрд╕рди рдлреНрд░реАрдореИрди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

[рез, реи] рд╕рдВрддреБрд╖реНрдЯ [рд╕рдВрдЦреНрдпрд╛] рдХрд╛ рдкреНрд░рд╢реНрди рдкреВрдЫрдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдз рд╣реИ
рдФрд░ рдмрд╣рд╕ред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╕реНрдкреНрд░реЗрдбреЗрдмрд▓ рдЯреБрдкрд▓реНрд╕ рдлреАрдЪрд░ рд╕реЗ рдХреНрдпрд╛ рд▓реЗрдирд╛-рджреЗрдирд╛ рд╣реИ?

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190453352
.

рдФрд░ рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдХрд╛рд░рдгреЛрдВ рд╕реЗ, рдореИрдВ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рддрд░рд╣ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛
рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ред

рд╕реЛрдо рдХреЛ, реиреп рдлрд░рд╡рд░реА, реирежрезрем, резреп:режреж рдЗрд╕рд┐рдпрд╛ рдореАрдбреЛрдЬ

рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдПрдХ рд╡рд┐рд╡рд┐рдз рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рддрд░реНрдХ рдпрд╛ рдирд╣реАрдВред рдЗрд╕ рдЕрддрд┐рднрд╛рд░рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ my . рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
рдЪрд┐рдВрддрд╛ред

declare function foo(x: number, ...args: string[]): void


declare function foo<T>(...args: [...T]): void
foo<[number]>(1, 2)

// This will always fail
declare function foo(x: number, ...args: string[]): void
declare function foo<T>(x: T): void
foo<number>(1, 2)

рд╕реЛрдо, реиреп рдлрд░рд╡рд░реА реирежрезрем рдХреЛ, резрео:рекрен рдЬреЗрд╕рди рдлреНрд░реАрдореИрди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com
рд▓рд┐рдЦрд╛ рдерд╛:

[рез, реи] рд╕рдВрддреБрд╖реНрдЯ [рд╕рдВрдЦреНрдпрд╛] рдХрд╛ рдкреНрд░рд╢реНрди рдкреВрдЫрдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдз рд╣реИ
рдФрд░ рдмрд╣рд╕ред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╕реНрдкреНрд░реЗрдбреЗрдмрд▓ рдЯреБрдкрд▓реНрд╕ рдлреАрдЪрд░ рд╕реЗ рдХреНрдпрд╛ рд▓реЗрдирд╛-рджреЗрдирд╛ рд╣реИ?

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190453352
.

@JsonFreeman рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рдХрд╛рд░ рдФрд░ рд╕рд░рдгреА/ A , B рдФрд░ T = [A] , рддреЛ рдлрд┐рд░ [...T, B] [A, B] рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдЧрд╛ " (рдЬреЛ рдирд┐рд╣рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИ) рддреЛ рдЗрд╕реЗ рд╕рд░рдгреА/рдЯреБрдкрд▓ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЧрдардмрдВрдзрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред var a: [A] рдФрд░ var b: B рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░ [...a, b] рдХреЛ [A, B] рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╛рдмрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЯреБрдкрд▓реНрд╕ рдХреЗ рдореМрдЬреВрджрд╛ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЗрд╕реЗ [A, A|B] рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рд╛рдмрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ? рдпрд╛ рдореИрдВ рдЙрд╕ рдмреЗрдореЗрд▓ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреБрд▓рдирд╛ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВред

@Igorbek рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдХрд╣ рд░рд╣реЗ рд╣реИрдВред рдпрд╣ рдЕрдВрддрддрдГ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЙрдкрдЬрд╛ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рдХ рдХреЛ рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдкреВрд░реНрдг рдЬреНрдЮрд╛рди рд╣реИ, рдЬрд┐рдирд╕реЗ рд╡рд╣ рдирд┐рдкрдЯ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХрд╛ рд╕рд╣реА рдЬреНрдЮрд╛рди рдирд╣реАрдВ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдорд╛рди a рдХреА рд▓рдВрдмрд╛рдИ рдЕрдЬреНрдЮрд╛рдд рд╣реИ, рдЬрдмрдХрд┐ рдкреНрд░рдХрд╛рд░ [A] рдХреА рд▓рдВрдмрд╛рдИ рдЬреНрдЮрд╛рдд рд╣реИред рдпрд╣ рдПрдХ рдХрд╛рд░рдг рдерд╛ рдХрд┐ рдореИрдВ рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╢реБрд░реВ рдореЗрдВ рдЕрд╕рд╣рдЬ рдерд╛ред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЧрдВрднреАрд░ рд╕рдорд╕реНрдпрд╛ рд╣реИред

@isiahmeadows рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБ рдХрд┐ рдЖрдк рдХрд┐рд╕ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдХреНрдпреЛрдВ рд╕реНрдкрд╖реНрдЯ рд╣реИ? рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рддрд░реНрдХ рд╣реИрдВ, рддреЛ рд╡рд╣реА рдкреНрд░рд╢реНрди рдкреВрдЫрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдмрд╛рдХреА рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕рдВрдЧрдд рд╣реЛрдЧрд╛
рднрд╛рд╖рд╛ рдЕрдЧрд░ рдпрд╣ рддрд░реНрдХ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреА рдирдХрд▓ рдХрд░рддреА рд╣реИред

рдореЗрд░рд╛ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдЖрд░рд╛рдо рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдлреИрд▓рд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдорд┐рд▓рддрд╛ рд╣реИ
рдмрд┐рд▓реНрдХреБрд▓ рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдФрд░ рдирд╣реАрдВред рдХрд░реАрдмреА рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╡рд╛рдкрд╕реА рд╣реЛрддреА рд╣реИ
рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдкреНрд░рдХрд╛рд░ред рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рддрд░реНрдХ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ
рдПрдХ рдХрд░реАрдмреА рд╕рдорд╛рд░реЛрд╣ рдХреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдорд┐рд▓реЗрдЧрд╛
рдкреНрд░рдХрд╛рд░ред рдЯреБрдкрд▓реНрд╕ рдЬреИрд╕реЗ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рд╕реЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА,
рдЬреЛ рдХрднреА рдЕрдЪреНрдЫреЗ рдирд╣реАрдВ рд╣реЛрддреЗред

рдордВрдЧрд▓, 1 рдорд╛рд░реНрдЪ, 2016, 06:07 рдХреЛ рдЬреЗрд╕рди рдлреНрд░реАрдореИрди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

@Igorbek https://github.com/Igorbek рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдХрд╣ рд░рд╣реЗ рд╣реИрдВред
рдпрд╣ рдЕрдВрддрддрдГ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЙрдкрдЬрд╛ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рдХ рдХреЛ рдкреВрд░реНрдг рдЬреНрдЮрд╛рди рд╣реИ
рдпрд╣ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХрд╛ рд╕рд╣реА рдЬреНрдЮрд╛рди рдирд╣реАрдВ рд╣реИред рдореЗрдВ
рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдорд╛рди рдХреА рдЕрдЬреНрдЮрд╛рдд рд▓рдВрдмрд╛рдИ рд╣реИ, рдЬрдмрдХрд┐
рдкреНрд░рдХрд╛рд░ [рдП] рдХреА рд▓рдВрдмрд╛рдИ рдЬреНрдЮрд╛рдд рд╣реИред рдпрд╣ рдПрдХ рдХрд╛рд░рдг рдерд╛ рдХрд┐ рдореИрдВ рд╢реБрд░реВ рдореЗрдВ рдерд╛
рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рд╣рдЬред рдХрд┐рдВрддреБ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ
рдпрд╣ рдПрдХ рдЧрдВрднреАрд░ рд╕рдорд╕реНрдпрд╛ рд╣реИред

@isiahmeadows https://github.com/isiahmeadows рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдкреВрдЫ рд░рд╣реЗ рд╣реИрдВ
рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рд▓реЗрдХрд┐рди рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛрдИ рд╕реНрдкрд╖реНрдЯ рдХреНрдпреЛрдВ рд╣реИ?

-
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ рдпрд╛ рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190667281
.

@isiahmeadows рдХреНрдпрд╛ рдЖрдк рдХрд░реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рджреЗ рд╕рдХрддреЗ рд╣реИрдВ?

рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рднрд▓реЗ рд╣реА рдЖрдкрдиреЗ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ (рдЬреЛ рдореИрдВ рд╕рднреА рдХреЗ рд▓рд┐рдП рд╣реВрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реЛ, рдЖрдкрдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ @isiahmeadows рд╕реЗ рд╕рд╣рдордд

@sandersn @JsonFreeman

type FullCurry<T> = ((initial: T, xs: T[]) => T) | ((initial: T) => (xs: T[]) => T)
declare function foldl<T>(func: (acc: T, item: T) => T, initial: T, xs: T[]): T
declare function foldl<T>(func: (acc: T, item: T) => T): FullCurry<T>
declare function foldl<T>(func: (acc: T, item: T) => T, initial: T): (xs: T[]) => T

interface Function<T, R, ...A> {
    apply<U extends T>(inst: U, args: [...A]): R
    apply(inst: T, args: [...A]): R
}

function apply(reducer: (initial: number) => number): (number[]) => number {
    reducer.apply(undefined, [0, []])
}

const func = apply(foldl<number>((x, y) => x + y))

func([1, 2, 3]) // Runtime error

рдореИрдВ рдЕрдкрдиреА рд╡рд┐рд╡рд┐рдзрддрд╛ рднреА рдЬреЛрдбрд╝реВрдВрдЧрд╛ред рдЖрдЗрдП рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ рд╡рд┐рд╡рд┐рдз рдХрд░реА рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ:

function curry<...T,...U,V>(f: (...ts: [...T, ...U]) => V, ...as:...T): (...bs:...U) => V {
    return ...b => f(...as, ...b);
}

рддреЛ рдлрд┐рд░, рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛:

function f(a: number, b: string, c: string) { return c.toUpperCase(); }
var a: [number, string] = [1, "boo", 2]; // valid
const cf = curry(f, ...a); // cf is of type string => string
cf("a"); // runtime error

@isiahmeadows рдЪрд╛рд╣реЗ рдЙрдиреНрд╣реЗрдВ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╛ рдЬрддрд╛рддреЗ рд╣реИрдВред

@Igorbek рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рдЙрджрд╛рд╣рд░рдг рд╕рдорд╛рди рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЙрдиреНрд╣реЗрдВ рдЯреБрдкрд▓реНрд╕ рдореЗрдВ рдлреИрд▓рд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ рдЬреЛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИред

@JsonFreeman рдпрд╣ рдЕрдзрд┐рдХ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдкрд░ рдЖрдкрддреНрддрд┐ рд╣реИ:

class A {}
class B {}
class C {}

declare function foo(a: A, b: B): C;

// This should not work
let value: [A, B, C]
foo(...value)

рдХреНрдпрд╛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ?

@isiahmeadows рдЗрд╕реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

@JsonFreeman
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣реА рдореЗрд░реА рд╕рдмрд╕реЗ рдмрдбрд╝реА рдЖрдкрддреНрддрд┐ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдРрд╕рд╛ рд╣реИ рддреЛ рдпрд╣ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЦрддрд░рдирд╛рдХ рд╣реИред

рдкреНрд░рд╢реНрди: ret рдХрд╛ рдЕрдиреБрдорд╛рдирд┐рдд рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

declare function foo(a: A, b: B, c: C, d: D): D
let ret = foo.bind(...[new A(), new B(), new D()])

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдлреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

рд╡рд╣ рдЖрдЦрд┐рд░реА рдЙрджрд╛рд╣рд░рдг рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдЗрд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЛ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдВрддреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдпрджрд┐ function.bind рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдареАрдХ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред рдЖрдкрдХреЛ рдПрдХреАрдХрд░рдг рдХреЗ рд╕рдорд╛рди рдХреБрдЫ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд╣рд╛рдВ рдмрд╛рдЗрдВрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдореВрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХреЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╢реЗрд╖ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред

рдЙрд╕ рдиреЗ рдХрд╣рд╛, рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдпрд╛ рдЪрд░реНрдЪрд╛ рдореЗрдВ рдХреБрдЫ рднреА рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ (рдЪрд╛рд╣реЗ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИ рдпрд╛ рдирд╣реАрдВ), рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖрдпрд╛ред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯрдкрд▓ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реНрдкреНрд░реЗрдб рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдЙрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ (рдПрдХ рд▓рд╛ рд▓рд╛рдЗрд╡рд╕реНрдХреНрд░рд┐рдкреНрдЯ/рдХреЙрдлреАрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рддрд░реНрдХ) рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╢рд╛рдпрдж рдЕрдиреНрдпрдерд╛ рдЕрд╕рдВрднрд╡ рд╣реИред рдФрд░ рдпрд╣ рдХрд┐рддрдирд╛ рдЬрдЯрд┐рд▓ рд╣реИ, рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрднрдХрд╛рдордирд╛рдПрдБред :рдореБрд╕реНрдХреБрд░рд╛рдУ:

@JsonFreeman

рдпрд╛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреИрд░-рд╕рдЦреНрдд (рдЙрддреНрд╕реБрдХ рдмрдирд╛рдо рдЖрд▓рд╕реА рдХреЗ рдЕрд░реНрде рдореЗрдВ) рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдореБрдЭреЗ рдпрд╣ рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╢рд╛рдпрдж рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рд╡рд┐рд╕реНрддрд╛рд░ рд╣реИ, рд╡реИрд╕реЗ рднреА, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рджрд░рд╡рд╛рдЬрд╛ рдЦреЛрд▓рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рд╕реНрд╡рдпрдВ-рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ред

// I hate this idiom.
interface NestedArray<T> extends Array<Nested<T>> {}
type Nested<T> = T | NestedArray<T>

// I would much prefer this, but it requires non-strict type checking.
type Nested<T> = T | Nested<T>[]

рд╢реБрдХреНрд░ рд╣реИ, рдЧреИрд░-рд╕рдЦреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХреЗрд╡рд▓ рдЙрд╕ рдХреЛрдб рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧреИрд░-рдмреНрд░реЗрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдЬреЛ рдкрд╣рд▓реЗ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣реА рдереАред

рд╢рд╛рдпрдж рдпрд╣реА рд╕рдмрд╕реЗ рдмрдбрд╝реА рдмрд╛рдд рд╣реИ рдЬреЛ Function.prototype.bind рдХреА рдЙрдЪрд┐рдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЛ рд░реЛрдХ рд░рд╣реА рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдпрд╣ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдХрдиреЗрдХреНрд╢рди рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ред рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдореБрджреНрджрд╛ рдЬреЗрдирд░рд┐рдХ рдХреЗ рд▓рд┐рдП рдХреИрд╢рд┐рдВрдЧ рдиреАрддрд┐ рдФрд░ рд╕рдВрдХрд▓рдХ рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдирд╛рдореЛрдВ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рд╕рд╛рд░реА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рд╣реИ рдЬреЛ рд░рд╛рд╕реНрддреЗ рдореЗрдВ рдЖрддрд╛ рд╣реИред

рдЯрдкрд▓ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП, рдЖрдк рд╣рдореЗрд╢рд╛ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рди рд╕рдХрддреЗ рдХрд┐ рдЯрдкрд▓ рдХреЗ рд╡рд┐рд░реБрджреНрдз рдХрд┐рддрдиреЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдорд┐рд▓рд╛рди рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдпрджрд┐ рдЖрдк bind рдХреЗ рддрд░реНрдХреЛрдВ рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдлреИрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдкрд░рд┐рдгрд╛рдореА рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдХрд┐рддрдиреЗ рд╢реЗрд╖ рд╣реИрдВред

@JsonFreeman рдХрд╣рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЧреЛрдж рд▓реЗрдиреЗ рдХреЗ рддрд░реНрдХ рдХреЗ рдПрдХ рдЪрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдСрдкрд░реЗрдЯрд░ рдкреНрд░рд╕реНрддрд╛рд╡ # 6229 рдХреЛ рдкрд╣рд▓реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

@JsonFreeman

рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЧреИрд░-рд╕рдЦреНрдд рдЬрд╛рдВрдЪ рдкрд░реНрдпрд╛рдкреНрдд рдЖрд▓рд╕реНрдп рдХреЛ Function.prototype.bind рд╕рд╛рде рдЙрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧреАред рдЗрд╕ рддрд░рд╣ рдХреЗ рдЖрд▓рд╕реНрдп рдХреЗ рд╕рд╛рде, рдЖрдк рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рд╕рд╛рде рдкреВрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯрдкрд▓ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрдм рддрдХ рдХрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рдореЗрдВ рдХрдИ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдареАрдХ рди рд╣реЛрдВ):

interface Function {
    bind<R, T, ...X, ...Y>(
        this: (this: T, ...args: [...X, ...Y]) => R,
        thisObject: T,
        ...args: [...X]
    ): (this: any, ...rest: [...Y]) => R
}

рдЗрд╕рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреИрд░-рд╕рдЦреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛрдЧреА? рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡рд┐рд░реБрджреНрдз рдЬрд╛рдБрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЛ рдЪрд░рдг рджрд░ рдЪрд░рдг рдШрдЯрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рд╣реЛрдЧрд╛:

// Values
declare function func(a: number, b: string, c: boolean, d?: symbol): number

let f = func.bind(null, 1, "foo")

// How to infer
bind<R, T, ...X, ...Y>(
    this: (this: T, ...args: [...X, ...Y]) => R,
    thisObject: T,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => R

// Infer first type parameter
bind<number, T, ...X, ...Y>(
    this: (this: T, ...args: [...X, ...Y]) => number,
    thisObject: T,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => number

// Infer second type parameter
bind<number, any, ...X, ...Y>(
    this: (this: any, ...args: [...X, ...Y]) => number,
    thisObject: any,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => number

// Infer first part of rest parameter
bind<number, any, number, ...*X, ...Y>(
    this: (this: any, ...args: [number, ...*X, ...Y]) => number,
    thisObject: any,
    ...args: [number, ...*X]
): (this: any, ...rest: [...Y]) => number

// Infer second part of rest parameter
bind<number, any, number, string, ...*X, ...Y>(
    this: (this: any, ...args: [number, string, ...*X, ...Y]) => number,
    thisObject: any,
    ...args: [number, string, ...*X]
): (this: any, ...rest: [...Y]) => number

// First rest parameter ends: all ones that only uses it are fully spread
bind<number, any, number, string, ...Y>(
    this: (this: any, ...args: [number, string, ...Y]) => number,
    thisObject: any,
    ...args: [number, string]
): (this: any, ...rest: [...Y]) => number

// Infer first part of next rest parameter
bind<number, any, number, string, boolean, ...*Y>(
    this: (this: any, ...args: [number, string, boolean, ...*Y]) => number,
    thisObject: any,
    ...args: [number, string]
): (this: any, ...rest: [boolean, ...*Y]) => number

// Infer second part of next rest parameter
// Note that information about optional parameters are retained.
bind<number, any, number, string, boolean, symbol?, ...*Y>(
    this: (
        this: any,
        ...args: [number, string, boolean, symbol?, ...*Y]
    ) => number,
    thisObject: any,
    ...args: [number, string]
): (this: any, ...rest: [boolean, symbol?, ...*Y]) => number

// Second rest parameter ends: all ones that only uses it are exhausted
bind<number, any, number, string, boolean, symbol?>(
    this: (this: any, ...args: [number, string, boolean, symbol?]) => number,
    thisObject: any,
    ...args: [number, string]
): (this: any, ...rest: [boolean, symbol?]) => number

// All rest parameters that are tuples get converted to multiple regular
parameters
bind<number, any, number, string, boolean, symbol?>(
    this: (
        this: any,
        x0: number,
        x1: string,
        x2: boolean,
        x3?: symbol
    ) => number,
    thisObject: any,
    x0: number,
    x1: string
): (this: any, x0: boolean, x1?: symbol) => number

// And this checks

рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЧреИрд░-рд╕рдЦреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХрд╛рдо рдХрд░рддреА рд╣реИред рдпрд╣ рддреБрд░рдВрдд рджреЗрдЦреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддрд╛ рд╣реИред рдЖрдк рджреЛ рдкрд╛рд╕реЛрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рдЪрд╛рд╣рд┐рдП), рддрд╛рдХрд┐ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдВред рдЙрджрд╛рд╣рд░рдг:

let f = func.bind(null, 1, Symbol("oops"))

// How to infer
bind<R, T, ...X, ...Y>(
    this: (this: T, ...args: [...X, ...Y]) => R,
    thisObject: T,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => R

// Infer first type parameter
bind<number, T, ...X, ...Y>(
    this: (this: T, ...args: [...X, ...Y]) => number,
    thisObject: T,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => number

// Infer second type parameter
bind<number, any, ...X, ...Y>(
    this: (this: any, ...args: [...X, ...Y]) => number,
    thisObject: any,
    ...args: [...X]
): (this: any, ...rest: [...Y]) => number

// Infer first part of rest parameter
bind<number, any, number, ...*X, ...Y>(
    this: (this: any, ...args: [number, ...*X, ...Y]) => number,
    thisObject: any,
    ...args: [number, ...*X]
): (this: any, ...rest: [...Y]) => number

// Infer second part of rest parameter
bind<number, any, number, string, ...*X, ...Y>(
    this: (this: any, ...args: [number, string, ...*X, ...Y]) => number,
    thisObject: any,
    ...args: [number, symbol /* expected string */, ...*X] // fail!
): (this: any, ...rest: [...Y]) => number

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдкреЗрдХреНрд╖рд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рдЙрд╕ рджреМрд░ рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдкрд╣рд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░ рд░рд╣рд╛ рд╣реЛред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЙрд╕ рдЦреЛрдЬ рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рдкрд╣рд▓рд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдерд╛, рдФрд░ рдкреНрд░рддреАрдХреЛрдВ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЙрд╕рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред


рдФрд░ рдЗрд╕ рд╡рдЬрд╣ рд╕реЗ рдФрд░ Function.prototype.apply рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреБрдкрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рдореЗрд░реА рд░рд╛рдп рдмрджрд▓ рдЧрдИ рд╣реИред

interface Function {
    apply<T, R, ...X>(
        this: (this: T, ...args: [...X]) => R,
        thisArg: T,
        args: [...X]
    ): R
}

рдХреБрдЫ рдЕрдиреНрдп рдиреЛрдЯ:

  1. рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░рдгрд┐рдпреЛрдВ рдФрд░ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдлреИрд▓рд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

ts interface Foo extends Function<void, ...string[]> {}

  1. рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░реНрд╕ рдФрд░ рдХреЙрд▓реЗрдмрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдореЗрдВ рдлрдВрдХреНрд╢рдиреНрд╕ рджреЛрдиреЛрдВ рдХрд╛ рдорд┐рд▓рди рд╣реЛред рдХреЙрд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХрдВрд╕реНрдЯреНрд░рдХреНрд╢рдирд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ ES5 рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рджреЛрдиреЛрдВ рдХреЗ рдорд┐рд▓рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
  2. Function.prototype.bind рдФрд░ рджреЛрд╕реНрддреЛрдВ рдХреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕рднреА рдУрд╡рд░рд▓реЛрдб рдХреЗ рдЦрд┐рд▓рд╛рдл рдЬрд╛рдВрдЪ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдХрдИ рдХрд╛рдо рд╣реИрдВ, рддреЛ рдЙрд╕реЗ рдЙрди рд╕рднреА рдХрд╛ рдПрдХ рд╕рдВрдШ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╡реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╛рдЗрдВрдб рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИрдВред рд╡реЗ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рд╛рдВ, рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рджреЛ рд░реЗрд╕реНрдЯ рдкреИрд░рд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЯреБрдкрд▓ рдореЗрдВ рджреЛ рд░реЗрд╕реНрдЯ рдЯрд╛рдЗрдк рдкреИрд░рд╛ рдХреЛ рдлреИрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рд▓рд┐рдЦ рдкрд╛рдПрдВрдЧреЗред

рдмрд╛рдЗрдВрдб рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд▓рдЪреАрд▓рд╛ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, ...X рдФрд░ ...Y рдмреАрдЪ рдХреА рд╕реАрдорд╛ рдХреЛ рдкреНрд░рддрд┐ рдХреЙрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рддрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдЧреА рдпрджрд┐ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ ...X рдерд╛ред рдРрд╕реЗ рдореЗрдВ рд╕реАрдорд╛ рддрдп рдирд╣реАрдВ рд╣реЛрдЧреАред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

interface SomeType<T, R, ...X, ...Y> {
     someMethod(someArgs): [...X]; // No way of knowing how long X is 
}

рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рднрд╛рд░ рдХрд╛рдлреА рд╕рдорд╕реНрдпрд╛ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рддрд░реНрдХ рдкрд░ рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рдХреЛ рддрддреНрд╡ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рд╕реЗ рдУрд╡рд░рд▓реЛрдб рдХреЗ рдмреАрдЪ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд┐рд╢реНрд░рдг рдФрд░ рдорд┐рд▓рд╛рди рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓ рдЬрд╛рдПрдЧреАред рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдЖрд╢рдп рдпрд╣реА рдерд╛?

@JsonFreeman

_TL; DR: рдХреНрд╖реИрддрд┐рдЬ рд░реЗрдЦрд╛ рд╡рд┐рд░рд╛рдо рдкрд░ рдЬрд╛рдПрдВред рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдирдпрд╛, рдЕрдзрд┐рдХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╡рд┐рдЪрд╛рд░ рд╣реИред_

  1. рд╣рд╛рдВ, рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Function рд╣реИрдВред
  2. рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдХрд╣рд╛ рдХрд┐ рдЧреИрд░-рд╕рдЦреНрдд рдкреНрд░рдХрд╛рд░ рдорд┐рд▓рд╛рди (рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЗ рдЕрд░реНрде рдореЗрдВ) рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЖрдк рдЙрддреНрд╕реБрдХрддрд╛ рд╕реЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╣рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрдд, рдЖрд▓рд╕реА рдЦреЛрдЬ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдПрд▓реНрдЧреЛрд░рд┐рджрдорд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЙрди рдЪреАрдЬреЛрдВ рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╕реА ++ рдореЗрдВ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
  3. рдпрджрд┐ рджреЛ рддрд░реНрдХ рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ рд╣реИрдВ (рдЬреИрд╕реЗ рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ), рддреЛ рд╕рдВрдХрд▓рдХ рдХреЛ рд╢рд┐рдХрд╛рдпрдд рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рднрд┐рдиреНрди рддрд░реНрдХ рдХреЗ рдкреНрд░рдХрд╛рд░-рд╕реНрддрд░ рдирд┐рд░реНрднрд░рддрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд╕рд╛рде/рдЬреЛ рдХреБрдЫ рднреА рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рднреА рддреБрдЪреНрдЫ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЯрд╛рдЗрдк рдбрд┐рдХреНрд▓реЗрд░реЗрд╢рди рдХреЛ рдкрдврд╝рддреЗ рд╕рдордп рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╢реАрдШреНрд░ рд╣реА рдмрд╛рдж рдореЗрдВ)ред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ рдпрд╣ рднреА рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдХреЗрд╡рд▓ рдкреНрд░рд╢реНрди рдореЗрдВ рд╡рд┐рдзрд┐ рдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдФрд░ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЙрди рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рднреА рдмрд╣реБрдд рдЖрд╕рд╛рди рдФрд░ рддреЗрдЬрд╝ рд╣реЛрдЧрд╛, рдЬрд┐рдирдХрд╛ рдЖрдкрдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдерд╛ред

interface Function<R, T, ...A> {
    // Split it up for just this method, since it's being resolved relative to the
    // method itself.
    bind[...A = ...X, ...Y](
        this: (this: T, ...args: [...X, ...Y]) => R,
        thisObject: T,
        ...args: [...X]
    ): (this: any, ...rest: [...Y]) => R
}

рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдмрд╣реБрдд рдХрдард┐рди рд╣реЛрдЧрд╛ (рдФрд░ рдореБрдЭреЗ рдХреНрдпреЛрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ 2 рддрдХ рд╕реАрдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рди рдХрд┐ _n _ рдбрд┐рд╡реАрдЬрдиреЛрдВ):

declare function foo<...T>[...T = ...A, ...B, ...C](
    a: [...A, ...C],
    b: [...A, ...B],
    c: [...B, ...C]
): any

// This should obviously check, but it's non-trivial to figure that out.
let x = foo<
    boolean, number, // ...A
    string, symbol,  // ...B
    Object, any[]  // ...C
>(
    [true, 1, {}, []],
    [true, 1, "hi", Symbol()],
    ["hi", Symbol(), {}, []]
)

_рдХреНрд╖рдорд╛ рдХрд░реЗрдВ рдпрджрд┐ рдореИрдВ рдпрд╣рд╛рдБ рд╕реАрдПрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдореЗрдВ рдмрд╣реБрдд рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдБ..._

рд╣рд╛рдБ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╣реА рд╡рд┐рдЪрд╛рд░ рд╣реИред рдпрд╣ рдмрд╣реБрдд рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдареАрдХ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП bind , рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдЬрд╛рдирдиреЗ Function ред рдЕрдВрддрд┐рдо рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдПрдХ рд╕реАрдорд╛ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ 2 рдмрд╛рд▓реНрдЯреА рддрдХ рд╕реАрдорд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдЖрдкрдХреЛ рдХреБрдЫ рдордирдорд╛рдиреА рд╕рдВрдЦреНрдпрд╛ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЗ рдмрдЬрд╛рдп 1 рд╕реАрдорд╛ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдкрдбрд╝реЗ, рдЬреЛ рд╕рдВрдпреБрдХреНрдд рд░реВрдк рд╕реЗ рдЙрдбрд╝рд╛ рд╕рдХрддреА рд╣реИред

рдРрд╕реЗ рдФрд░ рднреА рдореБрджреНрджреЗ рд╣реИрдВ рдЬрд┐рди рдкрд░ рд╣рдордиреЗ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред

@JsonFreeman рдПрдХ рдФрд░ рдореБрджреНрджрд╛ curry рдЬреИрд╕реА рдЪреАрдЬреЗрдВ рд╣реИрдВред рдореБрдЭреЗ рдЕрднреА рддрдХ рдРрд╕рд╛ рдХреБрдЫ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдареАрдХ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░ рд╕рдХреЗред рдФрд░ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдореИрдВ рдХрд░ рд╕рдХреВрдВ, рдЗрд╕рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред рдРрд╕реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдХреБрдЫ рдЧрдВрднреАрд░ рд╣рд╛рд╕реНрдХреЗрд▓-рдЬреИрд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рд╣реИрдХрд┐рдВрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдХрд┐ рдмреНрд▓реВрдмрд░реНрдб рдХреЗ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред

interface PromiseConstructor {
    // all same type
    all<T>(promises: PromiseLike<T>[]):  Promise<T[]>;
    join<T>(...promises: PromiseLike<T>[]):  Promise<T[]>;
    // varying types
    all<...T>(promises: [...PromiseLike<T>]): Promise<[...T]>;
    join<...T>(...promises: [...PromiseLike<T>]): Promise<[...T]>;
    // this is sketchy...    ^
}

interface Promise<T> {
    // all same type
    then<U>(onFulfill: (values: T) => U): Promise<U>;
    spread<U>(onFulfill: (...values: T) => U): Promise<U>;
}
interface Promise<...T> {
    // varying types
    then<U>(onFulfill: (values: [...T]) => U): Promise<U>;
    spread<U>(onFulfill: (...values: [...T]) => U): Promise<U>;
}

рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдкрд░реЛрдХреНрдд all<...T>(promises: [...PromiseLike<T>]): Promise<...T>; рд▓рд┐рдП рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рд╣реИ?

@DerFlatulator

PromiseConstructor рдореЗрдВ рдореЗрд░реА рдмрдбрд╝реА рдЯрд┐рдкреНрдкрдгреА рджреЗрдЦреЗрдВред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдереЛрдбрд╝рд╛ рдХрд░реАрдм рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рдкреНрд░реЙрдорд┐рд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рднреА рдареАрдХ рдХрд┐рдпрд╛ рд╣реИред

interface PromiseConstructor {
    new <T>(callback: (
        resolve:
        (thenableOrResult?: T | PromiseLike<T>) => void,
        reject: (error: any) => void
    ) => void): Promise<T, [T]>;
    new <...T>(callback: (
        resolve:
        (thenableOrResult?: [...T] | PromiseLike<[...T]>) => void,
        reject: (error: any) => void
    ) => void): Promise<[...T], ...T>;

    // all same type
    all<T>(promises: PromiseLike<T>[]):  Promise<T[], ...T[]>;
    join<T>(...promises: PromiseLike<T>[]):  Promise<T[], ...T[]>;

    // varying types
    all<...T>(promises: [...PromiseLike<T>]): Promise<[...T], ...T>;
    join<...T>(...promises: [...PromiseLike<T>]): Promise<[...T], ...T>;

    // all<...T>(promises: [...PromiseLike<T>]): Promise<[...T], ...T> should
    // expand to this:
    //
    // all<T1, T2, /* ... */>(promises: [
    //     PromiseLike<T1>,
    //     PromiseLike<T2>,
    //     /* ... */
    // ]): Promise<[T1, T2, /* ... */], T1, T2, /* ... */>;
    //
    // This should hold for all rest parameters, potentially expanding
    // exponentially like ...Promise<[Set<T>], ...Thenable<T>> which should
    // expand to something like this:
    //
    // Promise<[Set<T1>], Thenable<T1>, Thenable<T2> /* ... */>,
    // Promise<[Set<T2>], Thenable<T1>, Thenable<T2> /* ... */>,
    // // etc...
}

interface Promise<T, ...U> {
    // all same type
    then<V>(onFulfill: (values: T) => V): Promise<[V], V>;
    spread<V>(onFulfill: (...values: T) => V): Promise<[V], V>;

    // all same type, returns tuple
    then<...V>(onFulfill: (values: T) => [...V]): Promise<[...V], ...V>;
    spread<...V>(onFulfill: (...values: T) => [...V]): Promise<[...V], ...V>;

    // varying types
    then<V>(onFulfill: (values: [...U]) => V): Promise<[V], V>;
    spread<V>(onFulfill: (...values: [...U]) => V): Promise<[V], V>;

    // varying types, returns tuple
    then<...V>(onFulfill: (values: [...U]) => [...V]): Promise<[V], ...V>;
    spread<...V>(onFulfill: (...values: [...U]) => [...V]): Promise<[V], ...V>;
}

рдпрджрд┐ [...Foo<T>] рд╡рд┐рд╕реНрддрд╛рд░ [Foo<T1>, Foo<T2>, /*... Foo<TN>*/] , рддреЛ рдХреНрдпрд╛ [...Foo<T,U>] рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рддреНрд░реБрдЯрд┐ рдпрд╛ рдПрдХ рд╕рдВрдпреЛрдЬрдиреАрдп рд╡рд┐рд╕реНрддрд╛рд░ рд╣реИ?

@DerFlatulator

  1. рдпрджрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ T рдпрд╛ U рд╕реЗ рдХреЛрдИ рдПрдХ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ, рддреЛ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдлреИрд▓рддрд╛ рд╣реИред рдорд╛рди рд▓реЗрдВ рдХрд┐ T рдПрдХ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ, рддреЛ рдпрд╣ [Foo<T1, U>, Foo<T2, U>, /*... Foo<TN, U>*/] ред
  2. рдпрджрд┐ рджреЛрдиреЛрдВ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдФрд░ рдЙрдирдХреА рд▓рдВрдмрд╛рдИ рдХрд╛ рд╕рд╣реА рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рд╕рдВрдпреЛрдЬрдиреАрдп рд╡рд┐рд╕реНрддрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ... рдЯреА рдХреА рд▓рдВрдмрд╛рдИ рдпреВ рдХреА рд▓рдВрдмрд╛рдИ)ред
  3. рдпрджрд┐ рди рддреЛ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рддреЛ рдпрд╣ рдПрдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рддреНрд░реБрдЯрд┐ рд╣реИред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдореИрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдХрд╛рд░рдгреЛрдВ рд╕реЗ 2 рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдкреБрд░рдЬреЛрд░ рд╡рд┐рд░реЛрдз рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░, рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдХреЗрд╡рд▓ рдкреНрд░рддрд┐-рд╡рд┐рдзрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

interface Function<R, T, ...A> {
    // Split it up for just this method, since it's being resolved relative to the
    // method itself.
    bind[...A = ...X, ...Y](
        this: (this: T, ...args: [...X, ...Y]) => R,
        thisObject: T,
        ...args: [...X]
    ): (this: any, ...rest: [...Y]) => R
}

_(рдЕрдЧрд░ рдХреЛрдИ рдмреЗрд╣рддрд░ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдЖ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдореИрдВ рд╕рдм рдХрд╛рди рд╣реВрдВред рдореБрдЭреЗ рдпрд╣ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдРрд╕рд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдЬреЛ рджреГрд╖реНрдЯрд┐рдЧрдд рд░реВрдк рд╕реЗ рд╡рд┐рд░реЛрдз рди рдХрд░реЗред)_

@isiahmeadows

2 рдХреЗ рд╕рд╛рде, рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рд╕ рдХреНрд░рдо рдореЗрдВ рд╣реЛрдЧрд╛?

[
Foo<T1, U1>, Foo<T2, U1>, /*... */ Foo<TN,U1>,
Foo<T1, U2>, Foo<T2, U2>, /*... */ Foo<TN,U2>,
/* ... */
Foo<T1, UN>, Foo<T2, UN>, /*... */ Foo<TN,UN>
]

рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд:

[
Foo<T1, U1>, Foo<T1, U2>, /*... */ Foo<T1,UN>,
Foo<T2, U1>, Foo<T2, U2>, /*... */ Foo<T2,UN>,
/* ... */
Foo<TN, U1>, Foo<TN, U2>, /*... */ Foo<TN,UN>
]

рдХреНрдпрд╛ рдпрд╣ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рднреНрд░рдо рдкреИрджрд╛ рдирд╣реАрдВ рдХрд░реЗрдЧреА? рд╢рд╛рдпрдж рдПрдХ рдЖрдпрд╛рдо рддрдХ рд╕реАрдорд┐рдд рд░рд╣рдирд╛ рд╣реА рд╕рдордЭрджрд╛рд░реА рд╣реЛрдЧреАред


рд╕реНрдкреНрд▓рд┐рдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдмрд╕ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕реБрдЭрд╛рд╡:

interface Function<R, T, ...A> {
    bind<[...X, ...Y] = [...A]>(
        this: (this: T, ...args: [...X, ...Y]) => R,
        thisObject: T,
        ...args: [...X]
    ): (this: any, ...rest: [...Y]) => R
}

@DerFlatulator

рдореИрдВ рджреВрд╕рд░реЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реВрдВред рдФрд░ рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рднреНрд░рдо рдкреИрджрд╛ рдХрд░реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рддрдХ рдпрд╣ рд▓рдЧрд╛рддрд╛рд░ рд╣реИ, рд▓реЛрдЧреЛрдВ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдЗрд╕рдХреА рдЖрджрдд рд╣реЛ рдЬрд╛рдПрдЧреАред рдпрд╣ рдПрдХ рдЕрд╕рд╛рдорд╛рдиреНрдп рдмрдврд╝рдд рдХрд╛ рдорд╛рдорд▓рд╛ рднреА рд╣реИ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЗрд╡рд▓ рдЙрди рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреНрдпрд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдпрд╛ рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдХреЛ рдкрд╣рд▓реА рдЬрдЧрд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдкрд░ рд╕рд╡рд╛рд▓ рдЙрдард╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдВ рдЗрд╕реЗ рднреА рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ, рдлрд┐рд░ рджреВрд╕рд░реЗ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рд╕реНрдпреВрдбреЛрдХреЛрдб рдХреА рддрд░рд╣:

for (let TT of T) {
  for (let UU of U) {
    expand(TT, UU);
  }
}

рдЙрдкрд░реЛрдХреНрдд рдХреБрдЫ рд╡рд┐рдЪрд╛рд░реЛрдВ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ ...

interface Function<TReturn, TThis, ...TArgs> {
    bind<
        [...TBound, ...TUnbound] = [...TArgs],
        TNewThis
    >(
        thisObject: TNewThis,
        ...args: [...TBound]
    ): Function<TReturn, TNewThis, ...TUnbound>
}

рдпрд╣рд╛рдВ, [...TBound, ...TUnbound] = [...TArgs] рдорд╛рдиреНрдп рд╣реИ рдХреНрдпреЛрдВрдХрд┐ ...TBound рдХреА рд▓рдВрдмрд╛рдИ args рдХреА рд▓рдВрдмрд╛рдИ рд╕реЗ рдЬрд╛рдиреА рдЬрд╛рддреА рд╣реИред рдпрд╣ TThis рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рднреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдПрдХ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдХреЗрд╡рд▓ this рдПрдХ рдмрд╛рд░ рдмрд╛рдЗрдВрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

interface IFoo { a: number }
interface IBar extends IFoo { b: boolean }
function f(a: number) { }

let x = f.bind(<IBar>{ a: 1, b: false }, 2); // inferred type: Function<number, IBar>
let y = x.bind(<IFoo>{ a: 1 }) // inferred type: Function<number, IFoo>

y рдХрд╛ рдЕрдиреБрдорд╛рдирд┐рдд рдкреНрд░рдХрд╛рд░ рдЧрд▓рдд рд╣реИ, рдпрд╣ Function<number, IBar> рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЪрд┐рдВрддрд╛ рдХрд╛ рд╡рд┐рд╖рдп рд╣реИ рдпрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП <T> рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореЗрдВ рддрд░реНрдХ рдкреЗрд╢ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рд╡рд┐рдХрд▓реНрдк 1

interface Function<TReturn, TThis, ...TArgs> {
    bind<
        [...TBound, ...TUnbound] = [...TArgs],
        TNewThis = TThis is undefined ? TNewThis : TThis
    >(
        thisObject: TNewThis,
        ...args: [...TBound]
    ): Function<TReturn, TNewThis, ...TUnbound>;
}

рд╡рд┐рдХрд▓реНрдк 2

interface Function<TReturn, TThis, ...TArgs> {
    bind<
        [...TBound, ...TUnbound] = [...TArgs],
        TThis is undefined,
        TNewThis
    >(
        thisObject: TNewThis,
        ...args: [...TBound]
    ): Function<TReturn, TNewThis, ...TUnbound>;

    bind<
        [...TBound, ...TUnbound] = [...TArgs],
        TThis is defined
    >(
        thisObject: any,
        ...args: [...TBound]
    ): Function<TReturn, TThis, ...TUnbound>;
}

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рд╕рдВрднрд╡рддрдГ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛрдЧрд╛ред

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдореЗрдВ рдЯрд╛рдЗрдк рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреА рдЪрд╛рд╣рд┐рдПред рдореИрдВ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ "рдмреНрд░реИрдХреЗрдЯ рд░рд┐рдореВрд╡рд░" рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЛрдЪрддрд╛ рд╣реВрдВ рдЬреЛ рд╕рд░рдгреА рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ/рдкреНрд░реЙрдкрд░реНрдЯреА рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ (рдЪрд░рдг 2 рдкреНрд░рд╕реНрддрд╛рд╡) рдХреЗ рд╕рд╛рде рдмрд┐рд▓реНрдХреБрд▓ рдЧрдардмрдВрдзрди рд╣реИред рдмрд╕ рддреБрд▓рдирд╛ рдХрд░реЗрдВ:

let a =        [1, 2];
let b = [0, ...a     , 3];
//      [0, ...[1, 2], 3]
//      [0,     1, 2 , 3]  // removed brackets

let c =               { a: 1, b: "b" };
let d = { e: true, ...c               , f: 3 };
//      { e: true, ...{ a: 1, b: "b" }, f: 3 };
//      { e: true,      a: 1, b: "b"  , f: 3 };

рдЖрдк рдЗрд╕реЗ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реЗрдЯ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗ рд░рд╣реЗ рд╣реИрдВ:

<...T> = <A, B, C>
...U<T> = <U<A>, U<B>, U<C>>

рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдСрдкрд░реЗрд╢рди рд╣реИред рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЗрд╕реЗ рдЙрдЪреНрдЪ рдХреНрд░рдо рдХреЗ рдирд┐рд░реНрдорд╛рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐:

<...(from R in T select U<R>)> // linq-like
<...(T[R] -> U<R>)> // ugly

@Igorbek рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдПрдХ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?

interface PromiseConstructor {
    all<
      ...T, 
      [...TThen] = ...(PromiseLike<@T> | @T)
    >(
      promises: [...TThen]
    ): Promise<[...T], ...T>;
}

рдЬрд╣рд╛рдВ ...Foo<<strong i="9">@T</strong>, U> рд╡рд┐рд╕реНрддрд╛рд░ [Foo<T1,U>, /*...*/, Foo<TN,U>] ред

...(PromiseLike<@T> | @T) рдлреИрд▓рддрд╛ рд╣реИ
[PromiseLike<T1>|T1, /*...*/, PromiseLike<TN>|TN]

рдХреБрдЫ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡рд┐рдХрд▓реНрдк:

  • ...Foo<&T,U>
  • (T) Foo<T,U>
  • (...T => Foo<T,U>)
  • for (T of ...T) Foo<T,U>

рдореИрдВ рдпрд╣рд╛рдВ @Igorbek рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред рдХрдо рд╕реЗ рдХрдо рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░рдг рдЕрдиреБрдХреНрд░рдо рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдХреА рддрд░рд╣ рдирд╣реАрдВ рд▓рдЧрддреЗ рд╣реИрдВ, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд╣рдо рдЕрднреА рднреА рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдзрд┐рдХ рдмреБрдирд┐рдпрд╛рджреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдореБрдЭреЗ рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ (рдХрдо рд╕реЗ рдХрдо рд╢реБрд░реБрдЖрдд рдореЗрдВ), рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╡рд╣рд╛рд░ рдмрд╣реБрдд рд╣реА рдЕрдиреБрдкрдпреБрдХреНрдд рд╣реИ, рдФрд░ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд▓реЛрдЧ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪреАрдЬреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ред рдореИрдВ рдХрдо рд╕реЗ рдХрдо рдЕрднреА рдХреЗ рд▓рд┐рдП @Igorbek рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдкрд╣рд▓реЗ рдПрдХ рдЙрдЪреНрдЪ-рдЖрджреЗрд╢ рдкреНрд░рдХрд╛рд░ рдореЙрдбрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдпрд╣ рдПрдХ рдЕрд░реНрде рдореЗрдВ map рдкрд┐рдВрдЧ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ)ред рдФрд░ рдЙрдЪреНрдЪ рдХреНрд░рдо рдкреНрд░рдХрд╛рд░ рдмрд┐рд▓реНрдХреБрд▓ рдХреБрдЫ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдЖрдк рдмрд╕ рдмреЛрд▓реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рддреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ: +1: рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╢рд╛рдпрдж рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдПред рднрд▓реЗ рд╣реА рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ, рдпрд╣ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд░рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЬрдЯрд┐рд▓ рд╣реИ, рдФрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рд╣реИрдХ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ, рдЯрд╛рдЗрдк-рд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдереЛрдбрд╝реА рджреЗрд░ рд╕реЗ рдЖ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ @Igorbek рд╕реЗ рднреА рд╕рд╣рдордд рд╣реВрдВред #1336 рдореЗрдВ рдХреА рдЧрдИ рдореЗрд░реА рдЯрд┐рдкреНрдкрдгреА рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реБрдП рдФрд░ рд╕реНрдкрд╖реНрдЯ 'рдкреИрдХ' рдФрд░ 'рдЕрдирдкреИрдХ' рдСрдкрд░реЗрдЯрд░реЛрдВ рд╡рд╛рд▓реЗ рд╕реА ++ рдкреИрд░рд╛рдореАрдЯрд░ рдкреИрдХрд┐рдВрдЧ рд╕реЗ рдЙрдзрд╛рд░ рд╡рд┐рдЪрд╛рд░ред

рдЯреБрдкрд▓ рдореЗрдВ рдкреИрдХрд┐рдВрдЧ рдкреНрд░рдХрд╛рд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЕрдиреБрд░реВрдк рд▓рдЧрддрд╛ рд╣реИ:

let [x, y, ...rest] = [1, 2, 3, 4, 5] // pack
foo(...params) // unpack
let all = [1, 2, ...other, 5] // unpack

// keep in mind this is already implemented, which kind of similar to mapping types
function map(arr) { ... }
let spreadingmap = [1, 2, ...map(other), 5];

рдЬрд┐рд╕рд╕реЗ <...T_values> = [T1, T2, T3, etc...] рдмрд╛рд░реЗ рдореЗрдВ рддрд░реНрдХ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдЬрдмрдХрд┐ рд╕реА ++ рдкреИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдирдкреИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЗрд▓рд┐рдкреНрд╕рд┐рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕рдВрдЧрдд рд╣реИред

module Promise {
  function all<...T_values>(   // pack into a tuple of types, conceptually identical to rest parameters
      values: [ (<PromiseLike<T*>> ...T_values) ]  // unpack, cast, then repack to tuple
  ): Promise<T_values> // keep it packed since T_values is a tuple of whatever types
}

@isiahmeadows @JsonFreeman рдмрд┐рдирд╛ рдореИрдкрд┐рдВрдЧ рдХреЗ рдЗрд╕

рд╕рд╛рде рд╣реА рдЬреИрд╕рд╛ рдХрд┐ #1336 рдореЗрдВ рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдПрдХ рд╡рд┐рд╡рд┐рдз Array.flatten рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?

@jameskeane рд╡рд╣ рдкрд╣рд▓рд╛ рдЖрдзрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рдЪрд╛рд░ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдордзреНрдп рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ (рдЬреЛ рдХреБрдЫ рдПрдкреАрдЖрдИ рд╣реИрдВ) рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рдХрд╡рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:

function foo<...T>(a: Foo, b: Bar, ...rest: [...T, Baz]): Foo;

рдпрд╣ Function.prototype.apply рдмрдирд╛рдо Function.prototype.call рднреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╡рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

#1336 рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдЗрд╕реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

angular.module('app').controller(['$scope', function($scope: ng.IScope) { /*etc...*/ }]);

interface IModule {
  controller(injectable: [...string[], () => any]);
}

рдореИрдВрдиреЗ рдкрдХрдбрд╝ рд▓рд┐рдпрд╛ рд╣реИ, рдФрд░ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдореИрдВ рднреЛрд▓реЗрдкрди рд╕реЗ рдорд╛рди рд░рд╣рд╛ рдерд╛ рдХрд┐ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╕рдЦреНрдд рд▓рдВрдмрд╛рдИ рдХреЗ рдереЗ; рдХреМрди рд╕рд╛ рдЖрдИрдПрдордУ рд╕рдмрд╕реЗ рд╕рд╣рдЬ рд╣реИред рддреЛ рдпрд╣ рдорд╛рдирддреЗ рд╣реБрдП рдХрд┐ рд╣рдореЗрдВ рд╕рдЦреНрдд рд▓рдВрдмрд╛рдИ рдХреЗ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ (#6229) рдорд┐рд▓рддреЗ рд╣реИрдВ, рдХреНрдпрд╛ рдореБрджреНрджреЗ рд╣реИрдВ?

@isiahmeadows рдордзреНрдп рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдорд▓реЗ рдХреЗ рдЖрдкрдХреЗ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХреНрдпрд╛ рдпрд╣ рд╕рдЦреНрдд рд▓рдВрдмрд╛рдИ рдЯреБрдкрд▓реНрд╕ рд╣реЛрдиреЗ рд╕реЗ рд╣рд▓ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ? рдореИрдВ ...rest: [...T, Baz] рдХреЛ рд╕реНрдкреНрд░реЗрдб рдЕрдирдкреИрдХрд┐рдВрдЧ рдХреЗ рд╕рдорд╛рди рд╣реА рдкрдврд╝ рд░рд╣рд╛ рд╣реВрдВ arr = [...other, 123] ред рдпрд╣ рд╡рд╣реА рдореБрджреНрджрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдиреЗ curry рд╕рд╛рде рдЙрдард╛рдпрд╛ рдерд╛, рд╣реИ рдирд╛?

рдЬрд╣рд╛рдВ рддрдХ apply рдФрд░ call , рддреЛ рдХреНрдпрд╛ рд╡реЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдЖрдЪреНрдЫрд╛рджрд┐рдд рдирд╣реАрдВ рд╣реИрдВ? (рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Function рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рд╡реИрд╕реЗ рднреА рдкреНрд░рдХрд╛рд░ рд░рдЦрдиреЗ рдореЗрдВ рдореВрд▓реНрдп рджреЗрдЦрддрд╛ рд╣реВрдВ)ред

// as in
const t: [any, string] & [number, any] = [1, "foo"]

interface Function<R, T, ...A> {
    bind<...Y, ...Z>(
        this: (this: T, ...args: A & [...Y, ...Z]) => R, // tricky bit, luckily intersecting tuples is pretty easy
        thisObject: T,
        ...args: Y
    ): (this: any, ...rest: Z) => R
}

@jameskeane

рд╡рд░реНрддрдорд╛рди рд╡рд┐рд╡рд┐рдз рдкреНрд░рд╕реНрддрд╛рд╡ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ #6229 рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрд╡реАрдХреГрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рдЕрд░реНрдерд╛рдд рдЯреБрдкрд▓реНрд╕ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдЦреНрдд рд╣реЛрддреЗ рд╣реИрдВ)ред

func.apply , func.bind , func.call , рдФрд░ _.curry , рдХреЗрд╡рд▓ рд╕рдорд╕реНрдпрд╛ func.bind , _.curry , рдФрд░ рджреЛрд╕реНрддреЛрдВ, рдпрд╛ рдЕрдзрд┐рдХ рдЖрдо рддреМрд░ рдкрд░ рдЖрдВрд╢рд┐рдХ рдЖрд╡реЗрджрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдХреБрдЫ рднреАред рдЖрдкрдХреЛ рдпрд╣ рднреА рдЪреБрдирдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреМрди рд╕рд╛ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдпрд╣ рдХреЗрд╡рд▓ рдкреНрд░рддрд┐-рд╡рд┐рдзрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

call рдФрд░ apply рдмрд╣реБрдд рд╕реАрдзреЗ рд╣реИрдВ:

type Callable<R, T, ...A> = (this: T, ...args: [...A]) => R;

interface Function<R, T, ...A> {
    call(this: Callable<R, T, ...A>, thisArg: T, ...args: [...A]): R;
    apply(this: Callable<R, T, ...A>, thisArg: T, args: [...A]): R;
}

bind рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛрдЧрд╛ред рд╕реНрдкреНрд▓рд┐рдЯ рдкреИрд░рд╛рдореАрдЯрд░реНрд╕ рдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдорд┐рд▓рд╛рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЙрддреНрд╕реБрдХрддрд╛ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдм рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рддрдХ рдХрд┐ рдкрд╣рд▓рд╛ рд╕реНрдкреНрд▓рд┐рдЯ рд╣рд╛рдл рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдирдкреИрдХ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред рдЗрд╕реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рд╕рдВрдХрд▓рдХ рдЗрд╕реЗ рдЕрд▓рдЧ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИред

// Function.prototype.bind
type Callable<R, T, ...A> = (this: T, ...args: [...A]) => R;
type Constructible<R, ...A> = new (...args: [...A]) => R;

interface Function<R, T, ...A> {
    // my proposed syntax for splitting a rest parameter
    bind[[...A] = [...X, ...Y]](
        this: Callable<R, T, ...A>
        thisArg: T,
        ...args: [...X]
    ): Callable<R, any, ...Y>;

    bind[[...A] = [...X, ...Y]](
        this: Constructible<R, ...A>
        thisArg: T,
        ...args: [...X]
    ): Constructible<R, ...Y>;

    bind[[...A] = [...X, ...Y]](
        this: Callable<R, T, ...A> & Constructible<R, ...A>
        thisArg: T,
        ...args: [...X]
    ): Callable<R, T, ...Y> & Constructible<R, ...Y>;
}

curry рдмреЗрд╣рдж рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ f(1, 2, 3) === f(1, 2)(3) === f(1)(2, 3) === f(1)(2)(3) . рди рдХреЗрд╡рд▓ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рджреЛ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдЬреИрд╕реЗ bind , рдкреНрд░рддрд┐-рд╡рд┐рдзрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрд╣реБрдд рд╣реА рдЖрджрд┐рдо рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

interface Curried<R, T, ...XS> {
    // none passed
    (): this;

    // all passed
    (this: T, ...args: [...XS]): R;
}

interface CurriedMany<R, T, X, ...YS> extends Curried<R, T, X, ...YS>  {
    // penultimate case, constraint that ...YS contains no parameters
    [[...YS] = []](arg: X): Curried<R, T, X>;

    // otherwise, split rest into ...AS and ...BS, with `A` used as the pivot
    // (basically, default case)
    [[...YS] = [...AS, A, ...BS]](
        ...args: [X, ...AS]
    ): CurriedMany<R, T, A, ...BS>;
}

function curry<R, T>(f: (this: T) => R): (this: T) => R;
function curry<R, T, X>(f: (this: T, arg: X) => R): Curried<R, T, A>;
function curry<R, T, X, ...YS>(
    f: (this: T, arg: X, ...args: [...YS]) => R
): CurriedMany<R, T, X, ...YS>;

рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рд╣реИ рдХрд┐ curry рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдЗрд╕реЗ рдЯреНрдпреВрд░рд┐рдВрдЧ-рдкреВрд░реНрдг рдмрдирд╛ рджреЗрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд░реАрдм рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рд░реЛрдХрдиреЗ рд╡рд╛рд▓реА рдкреНрд░рд╛рдердорд┐рдХ рдЪреАрдЬ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реЛрдЧреА (рдЬреЛ рд╕реА ++, рд╕реНрдХреИрд▓рд╛ рдФрд░ рд╣рд╛рд╕реНрдХреЗрд▓, рдЯреНрдпреВрд░рд┐рдВрдЧ-рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рд╕рд┐рд╕реНрдЯрдо рд╡рд╛рд▓реА рддреАрди рднрд╛рд╖рд╛рдПрдВ, рд╕рднреА рд╣реИрдВ)ред

@sandersn рдореИрдВ рдКрдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрд╛, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдореИрдВ рд╡рд┐рд╡рд┐рдз рдорд╛рдирдХреЛрдВ рдкрд░ рдмрд╛рдзрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫ рд╕рдХрддрд╛ рд╣реВрдВ?

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

interface HasKey<T> {
    Key(): T;
}

class Row<...T extends HasKey<X>, X> {
    // ...
}

_рд╕рдВрдпреЛрдЧ рд╕реЗ, X рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЫреЛрдбрд╝рдиреЗ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП https://github.com/Microsoft/TypeScript/issues/7848 рджреЗрдЦреЗрдВред

рдЕрдм рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдпрд╣рд╛рдВ рдХреБрдЫ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдмрд╛рдзрд╛ рд╣реИ:

  1. (...T) extends HasKey<X> рдпрд╛
  2. ...(T extends HasKey<X>)

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдореИрдВ 2 рдорд╛рди рд░рд╣рд╛ рд╣реВрдБред

рдХреНрдпрд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдмрд╛рдзрд╛рдПрдВ (1 рдФрд░/рдпрд╛ 2) рд╕рдВрднрд╡ рд╣реЛрдВрдЧреА?

@myitcv 2 рд╢рд╛рдпрдж рдЬрд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдорд╛рд░реНрдЧ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдмрд╛рдзрд╛ рдХреА рдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

рдЕрдЪреНрдЫрд╛ ... рдореБрдЭреЗ рдЕрднреА рдХреБрдЫ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ: рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд╡рд╛рд▓реЗ рд╕рд░рдгреА рдХреИрд╕реЗ рд╣реЛрдВрдЧреЗ? рдпрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдиреАрдЪреЗ arg рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИ?

function processItems<...T>(...args: [...T]): void {
    for (const arg of args) { // Here
        process(arg);
    }
}

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдкреВрдЫ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ args рдХрд╛ рддрддреНрд╡ рдкреНрд░рдХрд╛рд░ рдХреНрдпрд╛ рд╣реИред рдЯреБрдкрд▓реНрд╕ рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рддрддреНрд╡реЛрдВ рдХрд╛ рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪ рд╕рдХрддрд╛ред

@sandersn рдХреНрдпрд╛ рдЖрдк рдЯрд┐рдкреНрдкрдгреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рдЪрд░реНрдЪрд╛ рд╣реБрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдлреАрдЪрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирд┐рд╢реНрдЪрд┐рдд рдпреЛрдЬрдирд╛ рд╣реИ, рдХреНрдпрд╛ рдпрд╣ рд╕рд╣реА рд╣реИ?

@JsonFreeman рдореИрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреВрдЫ рд░рд╣рд╛ рдерд╛ рдХрд┐ arg рдерд╛ред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ рдореЗрд░реЗ рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП any рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдиреАрдЪреЗ рдХреЗ рд╕рд╛рде Item<T> (рдПрдл-рдмрд╛рдЙрдВрдбреЗрдб рдЯреА рдХреЗ рд╕рд╛рде):

function processItems<...T extends Item<T>>(...args: [...T]): void {
    for (const arg of args) { // Here
        process(arg);
    }
}

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рддрд╛рдХрд┐ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рдВрдХрд▓рди рдХреЛ рдмрд╣реБрдд рддреЗрдЬ рдХрд░ рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рднреАрддрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рддрд░реНрдХ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ typeof arg рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛, рдФрд░ рд╕рдВрднрд╡рддрдГ рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛ред

рдУрд╣ рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ рдХрд┐ рдкреНрд░рдХрд╛рд░ T рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рджрд░рдЕрд╕рд▓, рдЖрдкрдХреЗ рджреВрд╕рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЯреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореЗрд░рд╛ рдорддрд▓рдм рджреВрд╕рд░реЗ рдореЗрдВ Item<any> рдерд╛...рдХреНрд╖рдорд╛ рдХрд░реЗрдВред

рдЬрдм рдореИрдВрдиреЗ рдХрд╣рд╛ рдХрд┐ рдпрд╣ рдЯреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдореИрдВ рдорд╛рди рд░рд╣рд╛ рдерд╛ рдХрд┐ рдЯреА рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдкреВрд░рд╛ рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдЯреА рдПрдХ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ)ред рддреЛ рд╣рд╛рдБ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ any рдФрд░ Item<any> рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд▓реЗрдХрд┐рди рдореЛрдЯреЗ рддреМрд░ рдкрд░, рдореИрдВ рдЙрддреНрд╕реБрдХ рд╣реВрдВ рдХрд┐ рдЯреАрдо 2.0 рдХреЗ рдмрд╛рдж рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдкрд░ рдХрд┐рддрдиреА рд╕рдХреНрд░рд┐рдпрддрд╛ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд░рд╣реА рд╣реИред рдореЗрд░реА рдХреЛрдИ рдордЬрдмреВрдд рд░рд╛рдп рдирд╣реАрдВ рд╣реИ, рдмрд╕ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВред

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдХрд╛рд░рдг T рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ T рд╣реИред рдЬрдм рддрдХ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдкрдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд┐рд╡рд┐рдз T рдпрд╛ рддреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд┐рд╡рд┐рдзрддрд╛ рдкреНрд░рдХрд╛рд░ рд╕реВрдЪреА рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рдЬрдм рдлреИрд▓рддрд╛ рд╣реИ, рддреЛ рд╕реВрдЪреА рд╕реНрд╡рдпрдВ, рдпрд╛рдиреА T рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рд╕рднреА рддрд░реНрдХреЛрдВ рдХрд╛ рдЙрдк рдкреНрд░рдХрд╛рд░ рд╣реИ рддрд░реНрдХ ...T , рдФрд░ [...T] T[] рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред

рдпрд╛, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕рднреА рдЕрд╕реНрдкрд╖реНрдЯ рд╢рдмреНрджрдЬрд╛рд▓ рдореЗрдВ рдореЗрд░рд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ, рдпрд╣рд╛рдБ рдХреЛрдб рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдореЗрд░рд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ:

// To put it into code
function foo<...T>(list: [...T]): void {
    // This is allowed
    let xs: T[] = list

    // This is allowed
    let list2: [...T] = list

    // This is not allowed
    let list1: [...T] = xs

    // This is allowed
    let item: ?T = null

    // This is not allowed, since it's not immediately initialized
    let other: T

    for (let arg of args) {
        // This is allowed
        let alias: T = arg

        // This is allowed
        let other: ?T = arg

        // This is allowed, since `item` is defined upwards as `?T`
        item = arg

        // This is allowed, since you're doing an unsafe cast from `?T` to `T`.
        alias = item as T
    }
}

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╢рд╛рдпрдж рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓рд╛ рд╣реЛрдЧрд╛ред

рдпрд╣ рдЕрднреА рднреА рд╣рдорд╛рд░реА рдЕрдЪреНрдЫреА рд╕реВрдЪреА рдореЗрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЗрдЦрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд░реБрдЪрд┐ рд░рдЦрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ - _n_ рдЕрдзрд┐рднрд╛рд░ - рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕ рдкрд░ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЕрдЧрд░ рдореБрдЭреЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реЛрддрд╛, рддреЛ рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ 2.1 рд╕рдВрднрд╡ рд╣реИ рд▓реЗрдХрд┐рди рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред

рдпрджрд┐/рдЬрдм рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рд░реЗрд╕реНрдЯ/рд╕реНрдкреНрд░реЗрдб (#2103) рдХрд╛ рдареАрдХ рд╕реЗ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрджреНрдз рд╣реИрдВ, рддреЛ рд╡реЗрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рдЙрди рд╕рднреА рдХреЛ рдПрдХ рд╕рд╛рде рдХрд░рдиреЗ рдХрд╛ рдФрдЪрд┐рддреНрдп рд╕рд╛рдмрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдлреИрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред (рд╕реНрдкреНрд░реЗрдб рдкреНрд░рдХрд╛рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛ { ...T, x: number, ...U, y: string, ...V } рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред)

рдХреЗрд╡рд▓ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ n overloads рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрдХреНрд╖рд╛рдУрдВ рдпрд╛ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдореЗрдВ рдореЗрд░реА рд╡рд┐рд╢реЗрд╖ рд░реБрдЪрд┐ рд╣реИред

@sandersn рдХреНрдпрд╛ bind , apply рдФрд░ call this рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "_n_ рдУрд╡рд░рд▓реЛрдб" рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдЖрдордВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдЕрд╕реНрдерд╛рдпреА рд╕рдордЭреМрддрд╛ рд╣реЛрдЧрд╛, рдФрд░ рдХреБрдЫ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХреБрдЫ рдмрдЧ рдкрдХрдбрд╝ рд╕рдХрддрд╛ рд╣реИред

@isiahmeadows

рдХрд╛рд░рдг рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдЬрд░реВрд░реА рдЯреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдЯреА рдХреНрдпрд╛ рд╣реИред

рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдЗрд╕ рдмрд╛рдд рдкрд░ рд╕рд╣рдорддрд┐ рд╣реИ рдХрд┐ T рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рд╣реИред рдЖрдкрдХреЗ рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, arg рдкреНрд░рдХрд╛рд░ рдЯреБрдкрд▓ рддрддреНрд╡ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдорд╛рди рд╣реЛрдЧрд╛ (рдЬреИрд╕рд╛ рдХрд┐

function processItems<...T>(...args: T): void {
  for (const arg of args) { // Here - arg:number|string|boolean
    const other: ??? = arg; // I think the issue is, how to _represent_ this type?
  }
}
processItems(1, 'foo', false); // T is tuple [number, string, boolean]

рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ рдЕрд▓рдЧ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЯреБрдкрд▓ рдХреЗ 'рддрддреНрд╡ рдкреНрд░рдХрд╛рд░' рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдкреНрд░рд╕рд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд ...T :: number|string|boolean ; рдЬреЛ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЛ рдлреИрд▓рд╛рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЗрд╕рдХреЗ рддрддреНрд╡ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред

for (const arg of args) {
  const cst: ...T = arg;
}

// also, even without variadic types...
type Record = [number, string];
function foo(args: Record) {
  for (const arg in args) {
    const cst: ...Record = arg;
  }
}

рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдЖрдкрдХреЗ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдг:

function foo<...T>(...list: T): void {
  let xs: T[] = [list, list] // array of the variadic tuple type

  // This is allowed
  let list5: (...T)[] = [...list]

  // This is *not* allowed
  let list2: [...T] = list

  // This is not allowed
  let list1: [...T] = xs

  // This **is** allowed
  // single element tuple, of variadic union
  // i.e. with number|string|boolean
  //      list4 = [1] or list4 = ['foo'] or list4 = [false]
  let list4: [...T] = [list[n]]

  // This **is**  allowed
  let other: T;

  // This is allowed
  let another: ...T;

  for (let arg of args) {
    another = arg; // allowed, if spreading the tuple is the union type

  }
}

рдЕрдкрдиреЗ рдореВрд▓ рд▓рдХреНрд╖реНрдп рдХреА рджреГрд╖реНрдЯрд┐ рди рдЦреЛрддреЗ рд╣реБрдП, рдореИрдВ рджреГрдврд╝рддрд╛ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рд╣реБрдЖ Promise.all рдЪрд╛рд╣рддрд╛ рдерд╛ ...

declare module Promise {
  function all<...T>(promises: Promise<...T>[]): T; // means promises is an array of promises to the union type, not what I wanted.

  // Then we need something like, which is now very confusing
  function all<...T>(promises: [...Promise<T*>]): T; 
}}

@sandersn рдЕрдм рдЬрдмрдХрд┐ рдЕрдиреНрдп рдЕрдиреБрд░реЛрдзрд┐рдд рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛрдиреЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? bind , call рдЖрджрд┐ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рдФрд░ ES рдмрд╛рдЗрдВрдб рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЕрдЧрд░/рдЬрдм рдпрд╣ рдмрд╛рд╣рд░ рдЖрддрд╛ рд╣реИ рддреЛ рдЙрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЕрдм рдЗрд╕ рдкрд░ рдЕрдзрд┐рдХ рд╕рд╡рд╛рд░реА рд╣реИ рд╡рд┐рдЪрд┐рддреНрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЗрдЦрдХ рдЖрдкрдХреЛ рд╣рд░ рд╕рдордп рдкрд░реЗрд╢рд╛рди рдХрд░рддреЗ рд╣реИрдВ . :)

рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд░рдЪрдирд╛рддреНрдордХ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реЛрдЧреА рдпрджрд┐ рдЗрди рджреЛ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдиреЗ рдЗрд╕реЗ 2.1 рдореЗрдВ рдмрдирд╛рдпрд╛ рд╣реИред рдореБрдЭреЗ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп (рдЖрд░рдПрдХреНрд╕рдЬреЗрдПрд╕) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рди рдХреЗрд╡рд▓ рдЗрди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рд╕реЗ рдХреЛрдбрдмреЗрд╕ рдореЗрдВ рд╕реБрдзрд╛рд░ рд╣реЛрдЧрд╛, рдЙрдкрднреЛрдЧ рдХреЛрдб рднреА рдХрд╛рдлреА рдХрдо рдЕрдЬреАрдм рд╣реЛрдЧрд╛ рдФрд░ рдмрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡рдг рд╣реЛрдЧрд╛ (рд╣рд░ рддреАрд╕рд░рд╛ рд╡реНрдпрдХреНрддрд┐ рдПрдВрдЧреБрд▓рд░ 2 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рд▓рд╛рдкрддрд╛ рдЖрдпрд╛рдд рд╕реЗ рдХрд╛рдЯ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЙрди рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЗрдВ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрдВ рдкреИрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)ред рд░рдЦрд░рдЦрд╛рд╡ рдпреЛрдЧреНрдп рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╕рдлрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрдЧреАред

рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ _.extend рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдЗрд╕рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рд╣реИ?

declare module underscore {
  function extend<A, B, C, D, ...>(a: A, b: B, c: C, d: D, ...): A&B&C&D&...;
}

рдЬреИрд╕рд╛ рдЦрдбрд╝рд╛ рд╣реИ рд╡реИрд╕рд╛ рдирд╣реАрдВред рдЗрд╕реЗ рдЙрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдП рдСрдкрд░реЗрдЯрд░ рдкрд░ рд╡рд┐рд╡рд░рдг рджреЗрддрд╛ рд╣реИ - рдЬрд┐рд╕реЗ рд╢рд╛рдпрдж & рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред @kitsonk рдиреЗ рдЗрд╕ рдСрдкрд░реЗрдЯрд░ рдХреЛ рдкрд╣рд▓реЗ рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдерд╛ред
рдЕрднреА рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдХреБрдЫ рдЕрдиреНрдп рддрддреНрдХрд╛рд▓ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЪреАрдЬреЛрдВ рдХреЗ рдиреАрдЪреЗ рд╣реИ рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдХреБрдЫ рд╕рдордп рдореЗрдВ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИред

рдкреВрд░реНрдг рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реБрдП, #10727 рд╕рдорд╛рдзрд╛рди рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ (рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ (@dojo) рдХреА рдЪреБрдиреМрддрд┐рдпреЛрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ)ред

рд╕реБрди рдХрд░ рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛! рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЕрднреА рднреА рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИред :( рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд╕рдкреНрддрд╛рд╣ рдЬрдм рдореИрдВрдиреЗ Object.assign рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛, рддреЛ рдореБрдЭреЗ рдпрд╣ рдмрд╣реБрдд рджреВрд░ рдорд┐рд▓рд╛:

interface Object {
  // binary version
  assign<T,U>(target: T, source: U): { ...T, ...U };
  // variadic version: bind a variadic kind variable ...T
  // and then spread it using SIX dots
  assign<...T>(...targets: ...T): { ......T };
}

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ "рд╕рд┐рдХреНрд╕ рдбреЙрдЯреНрд╕" рд╕рд┐рдВрдЯреИрдХреНрд╕ рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реНрдкреНрд░реЗрдб рд╣реИ, рдЬрд┐рд╕рдХреА рд╣рдордиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ рдХреА рд╣реИред

@sandersn

рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ Object.assign рд╕рд╛рде, рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдПрдХ рд╕рдмрд╕реЗрдЯ рдХреЛ рдХреИрдкреНрдЪрд░

assign<T>(target: T, ...sources: Partial<T>[]): T;

рдЗрд╕рдХреЗ рд╕рд╛рде рдЧрдбрд╝рдмрдбрд╝ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдкрдиреЗ рд▓рдХреНрд╖реНрдп рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЬрдЧрд╣ рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред

@isiahmeadows рддрдм рдЕрдиреБрдорд╛рди T рдХреЛ target рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ sources рд▓реЗрдЦрд╛рдВрдХрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдареАрдХ рдХрд░ рджреЗрдЧрд╛ред рдЖрдк рдЗрд╕реЗ рдЕрдм рдЧреИрд░-рд╡реИрд░рд┐рдПрдбрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВ:

declare function _assign<T>(target: T, source: Partial<T>): T;
_assign({}, { a: 10 }); // T is {}

рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, assign _a рд╕реНрдкреНрд░реЗрдб рдкреНрд░рдХрд╛рд░_ #10727 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

// non variadic
declare const assign: {
  <T>(target: T): T;
  <T, S>(target: T, source: S): {...T, ...S};
  <T, S1, S2>(target: T, source1: S1, source2: S2): {...T, ...S1, ...S2};
};
// variadic
declare function assign<T, [...S]>(target: T, ...sources: [...S]): {...T, ...[...S]};

_рдиреЛрдЯ: рдореИрдВ рдЕрднреА рднреА рдЯрдкрд▓-рдЖрдзрд╛рд░рд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкрд░ рдЬреЛрд░ рджреЗ рд░рд╣рд╛ рд╣реВрдВ [...T] рдЬреЛ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред_

@sandersn BTW, рдХреНрдпрд╛ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рд╣реИ рдЬрдм рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрддрд░рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВ? рдХреНрдпрд╛ рдЗрд╕реЗ 2.2 рдореЗрдВ рджреЗрдЦрдиреЗ рдХрд╛ рдХреЛрдИ рдореМрдХрд╛ рд╣реИ?
рдФрд░, рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ, рдХреНрдпрд╛ рдЖрдк рдЕрднреА рднреА рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдЖрдк рд╕рднреА рдЗрд╕рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ?

рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдФрд░ рдирд┐рдореНрди рд╕реНрддрд░ рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рдЕрднреА рддрдХ рдХреЛрдИ рд╕реНрдкрд╖реНрдЯ рд╕рд╣рдорддрд┐ рдирд╣реАрдВ рд╣реИред

рдордВрдЧрд▓рд╡рд╛рд░, 13 рджрд┐рд╕рдВрдмрд░ 2016 рдХреЛ, 13:26 рдЗрдЧреЛрд░ рдУрд▓реЗрдирд┐рдХреЛрд╡ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

@sandersn https://github.com/sandersn BTW, рдХрдм рдкрд░ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рд╣реИ?
рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрддрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ? рдХреНрдпрд╛ рдЗрд╕реЗ 2.2 рдореЗрдВ рджреЗрдЦрдиреЗ рдХрд╛ рдХреЛрдИ рдореМрдХрд╛ рд╣реИ?
рдФрд░, рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ, рдХреНрдпрд╛ рдЖрдк рдЕрднреА рднреА рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛
рдЖрдк рд╕рдм рдЗрд╕рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ?

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment-реиремремреорез реп
рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AERrBIa5fE8PSk-33w3ToFqHD9MCFoRWks5rHuM5gaJpZM4GYYfH
.

рдЗрд╕ рдореБрджреНрджреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ рдЗрд╕ рдкрд░ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?

рддреЛ рдЖрдк рдХрд┐рд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд░рд╣реЗ рд╣реИрдВ? рдХреНрдпрд╛ рдпрд╣ рдЯреАрдо рдХреЗ рдПрдЬреЗрдВрдбреЗ рдореЗрдВ рд╣реИ? рдпрд╣ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрдордЬреЛрд░ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдмрд╛рд░-рдмрд╛рд░ рдЪрд▓рд╛рддрд╛ рд╣реВрдВред рдореЗрд░реЗ рдкрд╛рд╕ рджреЛ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рд╣реИрдВред рдПрдХ рд╕рд░рд▓ рдФрд░ рдЬрдЯрд┐рд▓, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдпред

рдПрдХ Tuple extends any[] рд╕реБрдкрд░рдЯрд╛рдЗрдк рдЬреЛрдбрд╝рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рдХреЗрд╡рд▓ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЙрдк-рдкреНрд░рдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╕реНрдкреНрд░реЗрдб any[] рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛:

declare interface Plugin<A: Tuple, P> {
  (...args: A): P | Promise<P>
}

const p: Plugin<[string, { verbose: boolean }], int> =
  (dest, { verbose = false }) => 4

рдлрд┐рд▓рд╣рд╛рд▓, ...args: T[] рдХреА рдЕрдиреБрдорддрд┐ рдХреЗрд╡рд▓ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдЕрдВрдд рдореЗрдВ рджреА рдЬрд╛рддреА рд╣реИред

рдЬрдЯрд┐рд▓ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдЕрдВрджрд░ рдХрд╣реАрдВ рднреА рдХрд╛рдиреВрдиреА рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП ...args: Tuple рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА (рдЬреЛ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯреБрдкрд▓реНрд╕ рдирд┐рд╢реНрдЪрд┐рдд-рд▓рдВрдмрд╛рдИ рд╡рд╛рд▓реЗ рд╣реИрдВ):

/**
 * Takes a function with callback and transforms it into one returning a promise
 * f(...args, cb: (err, ...data) => void) => void
 * becomes
 * g(...args) => Promise<[...data]>
 */
function promisify<A extends Tuple, D extends Tuple, E>
    (wrapped: (...args: A, cb: (error: E, ...data: D) => void) => void)
    : ((...args: A) => Promise<Data>) {
  return (...args) => new Promise((resolve, reject) =>
    wrapped(...args, (e, ...data) =>
      e ? reject(e) : resolve(data)))
}

const write: ((fd: number, string: string, position?: number, encoding?: string)
              => Promise<[number, string]>) =
  promisify(fs.write)

рд╣рд╛рдБ, рдореИрдВрдиреЗ рдХрд▓ рд╣реА рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХреА рд╣реИ рдФрд░ рдЗрд╕рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореЗрд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдмрдирд╛ рджрд┐рдпрд╛ рд╣реИ (рдореИрдВ рдЕрднреА рднреА рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ) рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ (рдЬреЛ рдкрд╣рд▓реА рдмрд╛рдд рд╣реИ) рдореИрдВрдиреЗ рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА!):

function portable(func) {
    return function(...args) {
        if (this === undefined) {
            return func(...args)
        } else {
            return func(this, ...args)
        }
    }
}

рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рд╕рднреА рдбреЗрдХреЛрд░реЗрдЯрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХреЗ рдФрд░ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╣рд╛рдВ рдПрдХ рдЦрд░рд╛рдм рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ Array рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛ рдкреИрдЪ рдХрд░рддрд╛ рд╣реИ flatMap рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде:

function _flatMap<T, R>(
    array: T[],
    iteratee: (item: T) => R[]
): R[] {
    let result: R[] = []
    for (const item of array) {
        for (const value of iteratee(item)) {
            result.push(value)
        }
    }
    return result
}

const flatMap = portable(_flatMap)
Array.prototype.flatMap = flatMap

flatMap([1,2,3,4], x => [x, x])
// Is the same as
[1,2,3,4].flatMap(x => [x, x])
// Is the same as
flatMap.apply([1,2,3,4], [x => [x, x]])
// Is the same as
flatMap.call([1,2,3,4], x => [x, x])

рдЕрдм рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ flatMap ( _flatMap ) рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ:

function flatMap<T, R>(this: T[], iteratee: (item: T) => R[]): R[]
function flatMap<T, R>(this: undefined, array: T[], iteratee: (item: T) => R[]): R[]

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдкреЛрд░реНрдЯреЗрдмрд▓ рдореЗрдВ types рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреЛ _flatMap рд╕реЗ рдирд╣реАрдВ рдирд┐рдХрд╛рд▓ рд╕рдХрддрд╛, рдлрд┐рд░ рд╕рдЬрд╛рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреА рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рднреАрддрд░ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдореИрдВ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд▓рд┐рдЦреЗрдВ:

// First argument to func is required for portable to even make sense
function portable<T, R, ...Params>(func: (first: T, ...rest: Params) => R) {
    // The arguments of calling with this is undefined should be simply
    // exactly the same as the input function
    function result(this: undefined, first: T, ...rest: Params): R
    // However when this is of the type of the first argument then the type
    // should be that the parameters are simply the type of the remaining
    // arguments
    function result(this: T, ...rest: Params): R
    function result(...args) {
        if (this === undefined) {
            return func(...args)
        } else {
            return func(this, ...args)
        }
    }
    return result
}

рдореИрдВ рдмрд╕ рдЗрд╕реЗ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рд╢реБрд░реБрдЖрддреА рдЕрдиреБрднрд╡ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдФрд░ рд╢рд╛рдпрдж рдПрдХ рдФрд░ рдорд╛рдорд▓рд╛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рд╡рд┐рдз рдЬреЗрдиреЗрд░рд┐рдХ рдХреНрдпреЛрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВред

@sandersn :

рдЗрд╕рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ - n рдЕрдзрд┐рднрд╛рд░

рдЬрдмрдХрд┐ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдЧрд▓рдд рдирд╣реАрдВ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдпрд╣рд╛рдВ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рдБ, рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдЗрд╕рдХреА рдХрдореА рдУрд╡рд░рд▓реЛрдб рдХреЛ рдЗрд╕ рдзрд╛рдЧреЗ рдореЗрдВ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХ рд╕рдХрддреА рд╣реИ; рдФрд░ рдлрд┐рд░ рднреА, рдЗрд╕ рдЫреЛрдЯреА рд╕реА рдЕрд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд┐рд╕реА рднреА рдЕрдзрд┐рднрд╛рд░-рдЖрдзрд╛рд░рд┐рдд рд╕рдорд╛рдзрд╛рди рдиреЗ рдЗрд╕реЗ рдЕрдм рддрдХ lib.d.ts рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рд╣реИред

рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рдереНрд░реЗрдб рдореЗрдВ рдХрдИ рд▓реЛрдЧреЛрдВ рдиреЗ рдЕрдкрдиреЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣рддрд╛рд╢ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдореВрд▓ рд░реВрдк рд╕реЗ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рди рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдФрд░ рднреА рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдХреЗ ...... , рд╕рд╛рде рд╣реА рд╕рд╛рде ...*X , [...T = ...A, ...B, ...C] , [...PromiseLike<T>] , <[...X, ...Y] = [...A]> , рдФрд░ <PromiseLike<T*>> ред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╕рднреА рдпрд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╣рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рдордЭ рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдФрд░ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЙрдореНрдореАрдж рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдпрд╣рд╛рдВ рдЬреЛ рднреА рд╕рдбрд╝рдХ рдЪреБрдирддреЗ рд╣реИрдВ рд╡рд╣ рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рд╕рд╛рдЗрдб рдиреЛрдЯ: рд░рд╛рдорджрд╛ рдХреЗ R.path рд╣рдордиреЗ рдУрд╡рд░рд▓реЛрдб рдХреА рд╣рдЬрд╛рд░-рдИрд╢ рд▓рд╛рдЗрдиреЛрдВ рдХреА рдПрдХ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЙрддреНрдкрдиреНрди рдХреА рдереА, рдЬреЛ рдЕрднреА рднреА рдЯрдкрд▓ рд╕рдорд░реНрдерди рд╕реЗ рдЪреВрдХ рдЧрдИ рдереА (рдХреНрд░рдордкрд░рд┐рд╡рд░реНрддрди рдЕрднреА рднреА рдХрдард┐рди рддрд░реАрдХреЗ рд╕реЗ рд╡рд┐рд╕реНрдлреЛрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реЛрдЧрд╛), рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рд╕рдВрдХрд▓рди рдХреЛ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирд╛ рдЕрдм рдФрд░ред рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╡рд╣рд╛рдВ рдПрдХ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдЦреЛрдЬ рдХреА рдЧрдИ (#12290)ред

рд╡реИрд╕реЗ, рдЖрдкрдиреЗ рдЕрднреА рддрдХ @Artazor рдФрд░ @Igorbek рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдирд╣реАрдВ рдХреА рд╣реИред рдЙрд╕ рдкрд░ рдЖрдкрдХреЗ рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рдереЗ?

рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдмрд╣рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ (рдкреНрд▓рд╕ # 6606) рд╣рдо рдХреБрдЫ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдХреБрдЫ рд╕рдорд╛рдзрд╛рди рдкреНрд░рд╕реНрддреБрдд рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдЧреЗ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реВрдВред

рдореБрдЭреЗ рдкрд╣рд▓реЗ рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЬрд╛рдиреЗ рджреЗрдВ рдЬрд╣рд╛рдВ рдПрдХ ... рдСрдкрд░реЗрдЯрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

v ... рд▓рд┐рдП | рдкрд░рд┐рднрд╛рд╖рд╛ (рдХреИрдкреНрдЪрд░) | рдЙрдкрдпреЛрдЧ (рдлреИрд▓рд╛рдирд╛)
-|-|-
рд╕рдорд╛рд░реЛрд╣ | type Fn = (...args: any[]) => {} | type Returns = typeof fn(...MyTuple); (#6606)
рд╕рд░рдгреА | рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдЯрдкрд▓ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд┐рдВрдЧред рдЗрдВрдбреЗрдХреНрд╕ рдПрдХреНрд╕реЗрд╕ + рд╕реНрдкреНрд░реЗрдб (рджрд╛рдПрдВ рджреЗрдЦреЗрдВ) + рд░рд┐рдХрд░реНрд╕рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред | type Arr = [Head, ...Tail];
рд╡рд╕реНрддреБ | рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд┐рдВрдЧред рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдмрд╕ Omit , #12215 рджреЗрдЦреЗрдВред | type Obj = { a: a, ...restObj }; (рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ, Overwrite , #12215 рджреЗрдЦреЗрдВ)
рдЬреЗрдирд░рд┐рдХ | type Foo<...T> рдХреЛ Foo<1, 2, 3> type Foo<...T> рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ [1, 2, 3 ] рдореЗрдВ T )ред рдордЬрд╝рд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдХрд┐рд╕ рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред | type Bar<A,B,C> рдХреЛ Bar<...[1,2,3]> ( A = 1 рдЖрджрд┐) рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред рдбрд┐рдЯреНрдЯреЛ, рдЙрди рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред
рдпреВрдирд┐рдпрдиреЛрдВ (рдмреЛрдирд╕) | ? | type Union = "a" | "b"; type MyTuple = ...Union; // ["a", "b"] (рдЖрджреЗрд╢ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реИ рд▓реЗрдХрд┐рди рдЯреБрдкрд▓реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпреВрдирд┐рдпрдиреЛрдВ/рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИред рд╡реИрд╕реЗ рднреА, рдпрд╣рд╛рдВ рдЧреБрдВрдЬрд╛рдЗрд╢ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИред)

рддреЛ рдХреЗрд╡рд▓ рджреЛ рдкреНрд░рдХрд╛рд░-рд╕реНрддрд░ ... рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬреЛ рддрддреНрдХрд╛рд▓ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИрдВ; рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рджреЛрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдБ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

declare function f<U, T>(head: U, ...tail: T): [U, ...T];

#6606 рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рджреВрд╕рд░рд╛ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ: рдлрд╝рдВрдХреНрд╢рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЕрдирдкреИрдХ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛, рдЬреИрд╕реЗ typeof f(...MyTuple) ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпреЗ рдЙрди рдХрдард┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИред рдпрд╣рд╛рдВ рдХреБрдЫ рд╕рдорд╛рдзрд╛рди рдкреЗрд╢ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:

@jameskeane :

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЯрдкрд▓ рдХреЗ 'рддрддреНрд╡ рдкреНрд░рдХрд╛рд░' рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП

рдпрджрд┐ рдЖрдк рдЙрдирдХреЗ рддрддреНрд╡реЛрдВ рдХрд╛ рд╕рдВрдШ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдореЗрд░рд╛ TupleToUnion ред

Promise.all

// helpers: `mapTuple` needs #5453 to define, #6606 to use
type TupleHasIndex<Arr extends any[], I extends number> = ({[K in keyof Arr]: '1' } & Array<'0'>)[I];
type Inc = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // longer version in gist
declare function mapTuple<F extends (v: T) => any, Tpl extends T[], T>(f: F, tpl: Tpl): MapFn<F, Tpl, T>;
type MapFn<
    F extends (v: T) => any,
    Tpl extends T[],
    T,
    // if empty tuple allowed:
    // I extends number = 0,
    // Acc = []
    // otherwise:
    I extends number = 1,
    Acc = [F(Tpl[0])]
> = { 1: MapFn<F, Tpl, T, Inc[I], [...Acc, F(Tpl[I])]>; 0: Acc; }[TupleHasIndex<Tpl, Int>];

declare module Promise {
  function all<Promises extends Promise<any>[]>(promises: Promises): typeof mapTuple(<T>(prom: Promise<T>) => T, Promises);
}

@рджрд╛рдирд╡рдХ :

_.extend

@sandersn :

Object.assign

рдпреЗ рджреЛрдиреЛрдВ рд░рд╛рдорджрд╛ рдХреЗ mergeAll рдХреЗрд╡рд▓ рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВред рдХреЛрдИ рдЫрд╣ рдбреЙрдЯреНрд╕ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ!

@isiahmeadows :

рдЗрд╕ рдореБрджреНрджреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ рдЗрд╕ рдкрд░ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?
рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдФрд░ рдирд┐рдореНрди рд╕реНрддрд░ рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рдЕрднреА рддрдХ рдХреЛрдИ рд╕реНрдкрд╖реНрдЯ рд╕рд╣рдорддрд┐ рдирд╣реАрдВ рд╣реИред

рдЕрдЧрд░ рдореИрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ рддреЛ рдЖрдк рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЪрд┐рдВрддрд┐рдд рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХреБрдЫ рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрдард┐рди рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЬреИрд╕реЗ рдХрд┐ curry рдФрд░ bind рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЙрдирдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдмрд╛рдж, рдЙрд╕ рд╡рд┐рд╢реЗрд╖ рдкрд░ рдореЗрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред
рд░рдгрдиреАрддрд┐ рдереЛрдбрд╝реА рд╕рдорд╛рди рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдЗрд░реНрдж-рдЧрд┐рд░реНрдж рдзреЛрдЦрд╛ рджреЗрдирд╛ рдХрд┐ рдпрд╣ рдХрд╣рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдирд┐рдХрд╛рд▓реЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рддрд░реНрдХреЛрдВ рдХреА рдЯрд╛рдЗрдк-рдЪреЗрдХ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред

// helpers in https://gist.github.com/tycho01/be27a32573339ead953a07010ed3b824, too many to include

// poor man's version, using a given return value rather than using `typeof` based on the given argument types:
function curry<Args extends any[], Ret>(fn: (...args: Args) => Ret): Curried<Args, Ret>;
type Curried<
  ArgsAsked,
  Ret,
  ArgsPrevious = [] // if we can't have empty tuple I guess any[] might also destructures to nothing; that might do.
> = <
  ArgsGiven extends any[] = ArgsGiven,
  ArgsAll extends [...ArgsPrevious, ...ArgsGiven]
      = [...ArgsPrevious, ...ArgsGiven]
  >(...args: ArgsGiven) =>
    If<
      TupleHasIndex<ArgsAll, TupleLastIndex<ArgsAsked>>,
      Ret,
      Curried<ArgsAsked, Ret, ArgsAll>
    >;

// robust alternative that takes into account return values dependent on input params, also needs #6606
function curry<F>(fn: F): Curried<F>;
type Curried<
  F extends (...args: ArgsAsked) => any,
  ArgsAsked extends any[] = ArgsAsked,
  ArgsPrevious = []
> = <
  ArgsGiven extends any[] = ArgsGiven,
  ArgsAll extends [...ArgsPrevious, ...ArgsGiven]
      = [...ArgsPrevious, ...ArgsGiven]
  >(...args: ArgsGiven) =>
    If<
      TupleHasIndex<ArgsAll, TupleLastIndex<ArgsAsked>>,
      F(...[...ArgsPrevious, ...ArgsGiven]),уАА// #6606
      Curried<ArgsAsked, Ret, ArgsAll>
    >;

// bind:
interface Function {
    bind<
        F extends (this: T, ...args: ArgsAsked) => R,
        ArgsAsked extends any[],
        R extends any,
        T,
        Args extends any[], // tie to ArgsAsked
        Left extends any[] = DifferenceTuples<ArgsAsked, Args>,
        EnsureArgsMatchAsked extends 0 = ((v: Args) => 0)(TupleFrom<ArgsAsked, TupleLength<Args>>)
        // ^ workaround to ensure we can tie `Args` to both the actual input params as well as to the desired params. it'd throw if the condition is not met.
    >(
        this: F,
        thisObject: T,
        ...args: Args
    ): (this: any, ...rest: Left) => R;
    // ^ `R` alt. to calc return type based on input (needs #6606): `F(this: T, ...[...Args, ...Left])`
}

рд╣рд╛рдБ, рдореИрдВрдиреЗ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ - рдмрд╕ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬреЛ рдХреБрдЫ рд╣реИ рдЙрд╕рдХреЗ рд╕рд╛рде рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ (+ рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдереЛрдбрд╝рд╛ рдФрд░ рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рдореИрдВ ...... , ...*X , [...T = ...A, ...B, ...C] , [...PromiseLike<T>] , <[...X, ...Y] = [...A]> , рдпрд╛ <PromiseLike<T*>> рдЦрд┐рд▓рд╛рдл рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реВрдВред рд▓реЗрдХрд┐рди рдЖрдИрдПрдордУ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рд╕рд┐рд░реНрдл ... рдЕрднреА рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЗрд╕реЗ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рддреЗ рд╣реБрдП рджреЗрдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореИрдВрдиреЗ bind рд▓рд┐рдП рддрд░реНрдХ рдмрд╛рдзрд╛ рд╣рд▓ рдХреАред

рдмрд╕ рд╢рд╛рдпрдж рдмреЗрд╡рдХреВрдлреА рднрд░рд╛ рд╕рд╡рд╛рд▓ред рдпрд╣ рдХрд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рдЖрд╢рд╛рдЬрдирдХ рджрд┐рдЦрддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдХреБрдЫ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдХреЛрдИ рднреА рднрд╛рд░реА рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЙрдиреНрдореБрдЦ рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рджрд╛ рд╕рдордп рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ --strict рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ _tsconfig.json_ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ, рдЕрдЧрд░ рдХреЛрдб рдХреЗ рдПрдХ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк-рдЪреЗрдХрд┐рдВрдЧ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдЖрд▓рд╕реНрдп рдпрд╛ рд╕рдордп рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг)ред
рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдпрд╣ рд╢рд╛рдпрдж рдПрдХ рдмреЗрд╡рдХреВрдлреА рднрд░рд╛ рд╕рд╡рд╛рд▓ рд╣реИ... ^_^

@ yahiko00 рддрд░рд╣ рдХрд╛ рд╡рд┐рд╖рдп, рд▓реЗрдХрд┐рди exclude рдЕрдиреБрднрд╛рдЧ рдореЗрдВ tsconfig рдпрд╛ рд╡рд┐рднрд┐рдиреНрди рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реНрддрд░реЛрдВ рдкрд░ рдЕрд▓рдЧ tsconfig s рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдореИрдВ рдПрдХ рдФрд░ рд╕реБрдЭрд╛рд╡ рднреА рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ & рдФрд░ | рдЗрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХрд▓ рдЯрдкрд▓ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ:

<...T>(...args:T): ...T&
// is the same as 
<t1, t2, t3>(...args:[t1, t2, t3]): t1 & t2 & t3;
// and
<....T>(...args:T): ...T|
// is the same as 
<t1, t2, t3>(...args:[t1, t2, t3]): t1 | t2 | t3;

@HyphnKnight рдХрд╛ рдЙрдкрд░реЛрдХреНрдд рд╕реБрдЭрд╛рд╡ рдЙрд╕ рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬреЛ рдореИрдВ рднреА рдХрд░ рд░рд╣рд╛ рд╣реВрдБред

рдореИрдВ рдПрдХ рдЕрд╕реНрд╡реАрдХрд░рдг рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд░ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рдореИрдВрдиреЗ рдкрд╣рд▓реА рдмрд╛рд░ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджреЗрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рддреЛ рдореБрдЭреЗ рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдХрд╛ "рдкреВрд░реНрд╡ рдХрд▓рд╛" рдХрд╛ рдкреЗрдкрд░ рдорд┐рд▓рд╛, рдЬрд┐рд╕реЗ рдореИрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛: http://www.ccs.neu.edu/racket/pubs/esop09-sthf.pdf

рдореИрдВ рдЗрд╕реЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдБ рдЫреЛрдбрд╝ рджреВрдБрдЧрд╛ред

рдореИрдВрдиреЗ рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдкреНрд░рдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХреБрдЫ рдкреАрдЖрд░ рдЦреЛрд▓реЗ:

  • [ ] #17884 рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдлреИрд▓рддрд╛ рд╣реИ (WIP)
  • [x] #резренреорепрео рдмрд╛рдХреА рдкреИрд░рд╛ рдирд┐рдХрд╛рд▓реЗрдВ (рддреИрдпрд╛рд░)
  • [ ] #резреорежрежрен рдЯрд╛рдЗрдк рдХреЙрд▓ (рдбрдмреНрд▓реНрдпреВрдЖрдИрдкреА) рдореЗрдВ рдлреИрд▓рддрд╛ рд╣реИ
const c = 'a' + 'b';

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдЕрдиреБрдорд╛рди рдкреНрд░рдХрд╛рд░ рдХрд╛ c 'ab' рди рдХрд┐ string

StackOverflow рдкрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рд╢реНрди: рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдЕрдВрддрд┐рдо рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░

@sandersn рдЖрдк рдкреНрд░рд╕реНрддрд╛рд╡ рдЗрд╕ рдорд╛рдорд▓реЗ рдХреЛ рдХрд╡рд░ рдХрд░реЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореИрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ, рдХреНрдпрд╛ рдпрд╣ рд╕рд╣реА рд╣реИ?

рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ 2 рд╕рд╛рд▓ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд╕реЗ, рдХреНрдпрд╛ рд╣рдореЗрдВ рдЕрднреА рднреА рдЖрд╢рд╛рдиреНрд╡рд┐рдд рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдирдорд╕реНрдХрд╛рд░!
рдореИрдВ рдПрдХ рдЬрдирд░реЗрдЯрд░ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рд╕рд░рдгреА рдХреА рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирдИ рд╕рд░рдгреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдореЗрдВ рд╕реЗ рддрддреНрд╡реЛрдВ рдХреЛ рдорд┐рд▓рд╛рддрд╛ рд╣реИ рдФрд░ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред
рдореИрдВ рдЗрд╕ рдЬрдирд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ for...of рд▓реВрдк рдореЗрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХреА рдЙрдЪрд┐рдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред
рдХреЛрдб (рдЧрд▓рддрд┐рдпрд╛рдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрднреА рддрдХ рдирд╣реАрдВ рдЪрд▓рд╛рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣реА рд╡рд╣ рд╣реИ рдЬреЛ рдореИрдВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ):

function* CombineEveryArgumentWithEveryArgument(...args: any[][]) {
    if (args.length < 1) {
        return [];
    }
    var haselements = false;
    for (var arg of args) {
        if (arg && arg.length > 0) {
            haselements;
        }
    }
    if (!haselements) {
        return [];
    }
    var indexes = [];
    for (var i = 0; i < args.length; i++) {
        indexes.push(0);
    }
    while (true) {
        var values = [];
        //One item from every argument.
        for (var i = 0; i < args.length; i++) {
            values.push(args[i][indexes[i]]);
        }
        if (indexes[0] + 1 < args[0].length) {
            yield values;
        }
        else {
            return values;
        }
        //Increment starting from the last, until we get to the first.
        for (var i = args.length; i > 0; --i) {
            if (indexes[i]++ >= args[i].length) {
                indexes[i] = 0;
            }
            else {
                break;
            }
        }
    }
}

рдЙрджрд╛рд╣рд░рдг рдЙрдкрдпреЛрдЧ:

for (let [target, child] of
    CombineEveryArgumentWithEveryArgument(targetsarray, childrenarray)) {

рдореИрдВ рдордзреНрдпрд╕реНрде рдЪрд░ рдмрдирд╛рдП рдмрд┐рдирд╛ рд▓рдХреНрд╖реНрдп рдФрд░ рдмрдЪреНрдЪреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрддрд╛ред

рдРрд╕рд╛ рдХреБрдЫ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛?

function * generator<...T[]>(...args: T[]): [...T]

@Griffork рд╕рд╣реА рдЕрднреНрдпрд╛рд╕, рдЬрдм рддрдХ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдИ рдЕрдзрд┐рднрд╛рд░ рдмрдирд╛рдирд╛ рд╣реИ
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд╛рджрд╛ рджреЗрдЦреЗрдВред рд╕рднреА рдкреНрд░рдХрд╛рд░
https://github.com/Microsoft/TypeScript/blob/master/lib/lib.es2015.promise.d.ts#L41 -L113

рдореБрдЭреЗ рдпрд╣ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдмрд╣реБрдд рднреНрд░рдорд┐рдд рд▓рдЧрддрд╛ рд╣реИ:

function apply<...T,U>(ap: (...args:...T) => U, args: ...T): U {

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд▓рдЧрддрд╛ рд╣реИ:

function apply<T, U>(ap: (...args: T) => U, args: T): U {

рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рд╕рд░рдгреА рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕реЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЯреАрдПрд╕ рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

function apply<T, U>(ap: (...args: T[]) => U, args: T[]): U {

рддреЛ args рдПрдХ рд╕рд░рдгреА рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг T рдХреЗ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ рд╣рдЯрд╛рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп TS рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ T рд▓рд┐рдП рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП

function apply(ap: (...args: [number, number]) => number, args: [number, number]): number {

рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдЪрд┐рдВрддрд╛рдПрдВ рдЙрдард╛рдИ рдЧрдИ рдереАрдВ рдФрд░ рдореИрдВ рдЙрди рд╕рднреА рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдордЭ рдирд╣реАрдВ рдкрд╛ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рд┐рд░реНрдл рдЙрд╕ рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд╡рд░реНрддрдорд╛рди рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рдпрд╣ рд╕рдордЭрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдХреЛ ... рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдФрд░ рдЯреБрдкрд▓реНрд╕ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╣рдЬ рд╣реЛрддреЗ рд╣реИрдВред

... рдЕрднреА рднреА рджреЛ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдЬреИрд╕реЗ [...T, ...U] ред

@felixfbecker
рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡

function apply<...T,U>(ap: (...args:T) => U, ...args: T): U {

рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ T рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ string рдФрд░ int рдХрд░рддреЗ рд╣реИрдВ, рддреЛ T [string, int] ред
рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдпрджрд┐ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреИрдЯрд░реНрди рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

function PickArguments<T>(a: T[]): [T];
function PickArguments<T, U>(a: T[], b: U[]): [T, U];
function PickArguments<T, U, V>(a: T[], b: U[], c: V[]): [T, U, V];
//More overloads for increasing numbers of parameters.

//usage:
var [a, b, c] = PickArguments(["first", "second", "third"], [1, 2, 3], [new Date()]);
var d = b + 1; //b and d are numbers.
var e = c.toDateString(); //c is a date (autocompletes and everything), e is a string.

рдлрд┐рд▓рд╣рд╛рд▓ рдпрджрд┐ рдЖрдк рдПрдХ рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЕрдзрд┐рднрд╛рд░ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рд╕рдВрднрд╡рддрдГ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИред ...T рдкреНрд░рд╕реНрддрд╛рд╡ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд╣рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЖрдкрдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡:

function apply<T, U>(ap: (...args: T) => U, args: T): U {

рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЙрдирдХреЗ рдкрд╛рд╕ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдКрдкрд░ рджрд┐рдП рдЧрдП рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рднреА рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди any ред

рдореБрдЭреЗ рдпрд╣ рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрддрд┐рд░рд┐рдХреНрдд ... рдХреЛ рдкрдврд╝рдирд╛ рдмрд╣реБрдд рдХрдард┐рди рд╣реИред
@felixfbecker рд╡рд┐рдЪрд╛рд░ рдХреА рддрд░рд╣, рдореБрдЭреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣реА рд╣реИ:

function apply<...T, U>(ap: (...args: ...T) => U, args: ...T): U {...}

apply<...T, рдкрдврд╝рддреЗ рд╕рдордп рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рджрд┐рдорд╛рдЧ рдореЗрдВ рдпрд╣ рдмрд╛рдд рдЖрддреА рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдлреИрд▓рддрд╛ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рд╣реИред

@ рдЧреНрд░рд┐рдлреЛрд░реНрдХ , рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ T рдЕрднреА рднреА [string, int] ред
рдпрд╣реА @felixfbecker рдХрд╛ рдЕрд░реНрде рд╣реИ "рдЯреАрдПрд╕ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЯреА рдХреЗ рд▓рд┐рдП рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп", рдХрдо рд╕реЗ рдХрдо рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВред

рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЙрдирдХреЗ рдкрд╛рд╕ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдКрдкрд░ рджрд┐рдП рдЧрдП рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рднреА рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрдВрдЧреЗред

@ рдЧреНрд░рд┐рдлреЛрд░реНрдХ рдирд╣реАрдВ, рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдореЗрдВ рдпрд╣ args рд╕рд░рдгреА рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдПрдЧрд╛ , рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЯреБрдкрд▓ рдореЗрдВ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рд╕реЗ рдЕрдкрдирд╛ рдкреНрд░рдХрд╛рд░ рджреЗрдЧрд╛ред ...args: T[] рдЙрди рд╕рднреА рдХреЛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░реЗрдЧрд╛ T , рд▓реЗрдХрд┐рди ...args: T (рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╣реИ) T рд▓рд┐рдП рдПрдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдПрдЧрд╛ред

рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп рд╕рдмрд╕реЗ рдкрд╣рд▓реА рдмрд╛рдд рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрддреА рд╣реИ<...T, рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдлреИрд▓рддрд╛ рдирд╣реАрдВ рд╣реИред

@unional рд╕рд╣рдордд рд╣реИрдВ, рдпрд╣реА рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рднреНрд░рдо рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред

@unional
рдореИрдВрдиреЗ рдЗрд╕реЗ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдкрдврд╝рд╛, рдореИрдВрдиреЗ рдЗрд╕реЗ "рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣рд░ рдмрд╛рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдлреИрд▓рд╛рдПрдВ" рдХреЗ рд░реВрдк рдореЗрдВ рдкрдврд╝рд╛ред
рдореЗрд░реЗ рд▓рд┐рдП, рдЗрд╕реЗ рдкрдврд╝рдХрд░

function apply<T, U>(ap: (...args: T) => U, args: T): U {

рдореИрдВ T рдХреБрдЫ рд╕рд░рдгреА рд╣реЛрдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реВрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП string[] )ред

рдФрд░ рдЗрд╕реЗ рдкрдврд╝рдирд╛:

function apply<T, U>(ap: (...args: T[]) => U, args: T[]): U {

рдореИрдВ рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рд╕рднреА рддрд░реНрдХ T (рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬреИрд╕реЗ string ) рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВред

рдКрдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреА рдУрд░ рдмрд┐рдВрджреБ рдкрд░реЛрдХреНрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рдордирдорд╛рдирд╛ рд░рд╛рд╢рд┐ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдЬреЗрдирд░рд┐рдХ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

@felixfbecker
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
рдУрд╣ рдареАрдХред рдЕрднреА рднреА рдпрд╣ рдордд рд╕реЛрдЪреЛ рдХрд┐ рдпрд╣ рд╕рд╣рдЬ рд╣реИред

рдореИрдВ рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЯреА рдХреБрдЫ рд╕рд░рдгреА рд╣реЛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ [])ред

рдПрдХ рдЯрдкрд▓ "рдХреБрдЫ рд╕рд░рдгреА" рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд▓рдВрдмрд╛рдИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП [string, number] (рдмрдирд╛рдо (string | number)[] , рдЬреЛ рдЕрдирдмрд╛рдЙрдВрдб рд╣реИ рдФрд░ рдпрд╣ рдШреЛрд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рддрддреНрд╡ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ рдкреНрд░рдХрд╛рд░)ред

рдареАрдХ рд╣реИ рддреЛ рдЖрдк рдХреНрдпрд╛ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЬрд┐рдХреНрд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ "рд╕рднреА рдорд╛рдирдХреЛрдВ рдХреЛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░реЗрдВ", рдЬреЛ ...args: T[] рджреНрд╡рд╛рд░рд╛ рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдореИрдВрдиреЗ рдЗрд╕реЗ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдкрдврд╝рд╛, рдореИрдВрдиреЗ рдЗрд╕реЗ "рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣рд░ рдмрд╛рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдлреИрд▓рд╛рдПрдВ" рдХреЗ рд░реВрдк рдореЗрдВ рдкрдврд╝рд╛ред

рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред
рдЬрдм рдЖрдк рдлреИрд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ, рдЖрдк рдХреБрдЫ рдРрд╕рд╛ рдШреЛрд╖рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ рдЬреЛ "рдлреИрд▓рд╛рдиреЗ рдпреЛрдЧреНрдп" рд╣реЛ:

const a = { x: 1, y: 2 }
const b = { ...a }

// likewise
function appendString<T>(...args: T): [...T, string] {
  args.push('abc')
  return args
}

рд╣рд╛рдВред рдпрджрд┐ рдЖрдк рдпрд╣ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреЛ "рдлреИрд▓рд╛рдиреЗ рдпреЛрдЧреНрдп" рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЬреЛ рдкреНрд░рддрд┐ ES рдХрд▓реНрдкрдирд╛ рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдЪрд▓рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП), рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ extends рд╕рд╛рде рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ:

function foo<T extends Iterable<any>>(spreadable: T): [...T, string] {
  return [...spreadable, 'abc']
}

const bar = foo([1, true])
// bar is [number, boolean, string]

рдмреЗрд╢рдХ, рдПрдХ рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдЬреНрдЮрд╛рдд рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ Iterable рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ Array рд╣реИред

рдЬреЛ, рд╣рдо рдЬреЛ рдХрд╣ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ: https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -189703556

рд▓реЗрдХрд┐рди рдПрдХ рд╕реАрдЯрд┐рдВрдЧ рдореЗрдВ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдХреА рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИред рдореИрдВ

рдЕрдЧрд░ рдЯрдкрд▓ рдХреЙрдиреНрд╕рдЯреЗрдиреЗрд╢рди рдЙрддрд░ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдо рдЪрд░реНрдЪ рдирдВрдмрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! рд╣реБрд░реНрд░реЗ!

type TupleSuc<T extends [...number]> = [...T, T['length']];
type TupleZero = [];  // as proposed, we need empty tuple
type TupleOne = TupleSuc<TupleZero>;
type Zero = TupleZero['length'];
type One = TupleOne['length'];

рдФрд░ рдЕрдЧрд░ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ, рддреЛ рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдЯрдкрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

type Tuple<N extends number, T = TupleZero> = T['length'] extends N ? T : Tuple<N, TupleSuc<T>>;
type TupleTen = Tuple<10>;
type Ten = TupleTen['length'];

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдореИрдВрдиреЗ рдпрд╣ рд╕рдм рдзрд╛рдЧрд╛ рдкрдврд╝рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдирдХреЛрдВ рдореЗрдВ ...T рд╣реЛрдиреЗ рдкрд░ рднреНрд░рдорд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИ,
рдХреНрдпреЛрдВ рди рд╡реИрд▓реНрдпреВ-рд▓реЗрд╡рд▓ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд┐рдВрдЧ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдЖрдЧреЗ рдорд┐рд░рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддрд╛рдХрд┐ [...T] рдХрд╛ рдЙрдкрдпреЛрдЧ a . рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ
рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рддрд░реНрдХ рд╕реНрдерд┐рддрд┐ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд╖реНрдЯ рдХрд░ рджреЗрддреА рд╣реИ рдпрджрд┐ рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░-рд╕реНрддрд░реАрдп рдЯреБрдкрд▓ рд╣реИ? рдЗрд╕рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА
рдЯреБрдкрд▓реНрд╕ рдХреЗ рд╕рд╛рде рдЯрд╛рдЗрдкрд┐рдВрдЧ рд░реЗрд╕реНрдЯ рдкреИрд░рд╛рдо рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдкрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдордХрдХреНрд╖ рдмрдирд╛ рджреЗрдЧрд╛
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ:

const first = (a: number, b: string) => тАж;
const second = (...ab: [number, string]) => тАж;

first(12, "hello"); // ok
second(12, "hello"); // also ok

INB4 "рд▓реЗрдХрд┐рди рдпрд╣ рдЯрд╛рдЗрдк-рдирд┐рд░реНрджреЗрд╢рд┐рдд рдЙрддреНрд╕рд░реНрдЬрди рд╣реИ" - рдирд╣реАрдВред рдпрд╣ рдЙрддреНрд╕рд░реНрдЬрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, first рдЕрднреА рднреА рджреЛ рд╣реИрдВ
рдЕрд▓рдЧ рддрд░реНрдХ рдЙрддреНрд╕рд░реНрдЬрд┐рдд, second рдореЗрдВ рдЕрднреА рднреА рдПрдХ рдЖрд░рд╛рдо рддрд░реНрдХ рд╣реЛрдЧрд╛ред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдмрджрд▓рддреА рд╣реИ рд╡рд╣ рд╣реИ
рдХрд┐ рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдкрд░, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ second рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░, рдХреНрд░рдо рдореЗрдВ, рдЯрдкрд▓ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ
[number, string] ред

рд╡реИрд╕реЗ рднреА, рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдо [...Type] рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо apply рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

function apply<
  [...ArgumentsT], // a type-level tuple of arguments
  ResultT
>(
  // the call site of `toApply` function will be used to infer values of `ArgumentsT`
  toApply:   (...arguments: ArgumentsT) => ResultT,
  arguments: ArgumentsT
) :
  ResultT
{
  // тАж
}

// NB: using my preferred formatting for complex type-level stuff; hope it's readable for you
// this is entirely equivalent to OP's notation version:
function apply<[...T], U>(ap: (...args: T) => U,  args: T): U {
  // тАж
}

// so at the call site of
const fn = (a: number, b: string, c: RegExp) => тАж;

// we have `ArgumentsT` equal to [number, string, RegExp]
apply(fn, [12, "hello" /s+/]); // ok, matches `ArgumentsT`
apply(fn, [12, /s+/]); // not ok, doesn't match `ArgumentsT`

[...Type] рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдореВрд▓реНрдп-рд╕реНрддрд░ рдХреЗ рд╡рд┐рдирд╛рд╢рдХрд╛рд░реА рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧрд╛, рд╡рд┐рднрд╛рдЬрди рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛
рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдЯреБрдкрд▓реНрд╕ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛:

type SomeType  = [string, number, "constant"];
type OtherType = ["another-constant", number];

type First<[First, ..._]> = FirstT;
type Rest<[_, ...RestT]> = RestT;
type Concat<[...LeftT], [...RightT]> = [...LeftT, ...RightT];
type FirstTwo<[FirstT, SecondT, ..._]> = [FirstT, SecondT];

// has type `string`
const aString: First<SomeType> =
  "strrriiing";
// has type `[number, "constant"]
const numberAndConstant: Rest<SomeType> =
  [42, "constant"];
// has type `[string, number, "constant", "another-constant", number]`
const everything: Concat<SomeType, OtherType> =
  ["herpderp", 42, "constant", "another-constant", 1337];
// has type `[string, number]`
const firstTwo: FirstTwo<SomeType> =
  ["striiiing", 42];

рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ curry рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВ, рдЗрд╕ рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг:

type Curried<
  [...ArgumentsT]
  ResultT,
  ArgumentT      = First<ArgumentsT>,
  RestArgumentsT = Rest<ArgumentsT>
> =
  // just ye olde recursione, to build nested functions until we run out of arguments
  RestArgumentsT extends []
    ? (argument: ArgumentT) => ResultT
    : (argument: ArgumentT) => Curried<RestArgumentsT, ResultT>;

// NB. with more complex generic types I usually use generic defaults as a sort-of
// of type-level variable assignment; not at all required for this, just nicer to read IMO

function curry<
  [...ArgumentsT],
  ResultT
>(
  function: (...arguments: ArgumentsT) => ResultT
) :
  Curried<ArgumentsT, ResultT>
{
  // do the magic curry thing here
}

// or in the short indecipherable variable name style

function curry<[...T], U>(fn: (...args: T) => U): Curried<T, U>
{
  // тАж
}

// this should let you do this (using `fn` from before)
const justAddRegex = curry(fn)(123, "hello");

justAddRegex(/s+/); // ok, matches the arguments of `fn`
justAddRegex(123); // not ok, doesn't match the arguments of `fn`

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╣рдиреЗ рдореЗрдВ рднреА рдорджрджрдЧрд╛рд░ рд╣реЛрдЧрд╛, рдХрд┐ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ рдПрдХ рдкреНрд░рдХрд╛рд░-рд╕реНрддрд░ рдХрд╛ рдЯрдкрд▓ рд╣реИ
рдХрд┐рд╕реА рддрд░рд╣ рдХреАред рддрдм рдореБрджреНрджрд╛ рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ - 2.7 рдХреЗ рдмрд╛рдж рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ?) рдЯрдкрд▓ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯрд┐рдмрд┐рд▓рд┐рдЯреА рд▓реЗрддрд╛ рд╣реИ
рдЦрд╛рддреЗ рдореЗрдВ рдЯрдкрд▓ рд▓рдВрдмрд╛рдИ - _any рдкреНрд░рдХрд╛рд░-рд╕реНрддрд░ tuple_ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдкрд░ рд╢рд╛рдпрдж рдХреБрдЫ рдРрд╕рд╛
[...] рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ? рдореЗрд░реЗ рдкрд╛рд╕ рдХреЛрдИ рдордЬрдмреВрдд рд░рд╛рдп рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╛рдо рдпреЛрдЧреНрдп рд╣реЛред

// bikeshed me
type OnlyTuplesWelcome<ArgumentT extends [...]> = ArgumentT;

рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ [...ArgsT] рдХрд╛ рдЙрдкрд░реЛрдХреНрдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореВрд▓ рд░реВрдк рд╕реЗ ArgsT extends [...] рд▓рд┐рдП рдПрдХ рд╢реЙрд░реНрдЯрд╣реИрдВрдб рд╣реЛ рд╕рдХрддрд╛ рд╣реИ,
рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдЯреБрдкрд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдкрд░ рдПрдХ рдмрд╛рдзрд╛ рдЖрддреА рд╣реИред

рд╡рд┐рдЪрд╛рд░?

@jaen :

(...ab: [number, string]) => тАж

рд╣рд╛рдБ, рдпрд╣ #4130 рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред рдореИрдВрдиреЗ #1804 рдкрд░ рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдореЗрд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдереЛрдбрд╝рд╛ рд╣реИрдХреА (рд╕рд┐рдВрдереЗрдЯрд┐рдХ рдиреЛрдбреНрд╕) рдерд╛ред

рдХрд┐рд╕реА рднреА рдЯреБрдкрд▓ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдкрд░ рдореИрдВрдиреЗ рдХрд┐рд╕реА рдХреЛ any[] & { 0: any } рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рджреЗрдЦрд╛, рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЦрд╛рд▓реА рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░ fwiw рддрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдЬреНрдпрд╛рджрд╛рддрд░ рд╕рд┐рд░реНрдл any[] ред

RxJS рдХреЛ рд╣рд░ рдЬрдЧрд╣ рдЗрд╕рдХреА рдЬрд░реВрд░рдд рд╣реИред рд╕рдмрд╕реЗ рдЧрдВрднреАрд░ рд░реВрдк рд╕реЗ Observable.prototype.pipe , рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рдЕрдзрд┐рднрд╛рд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд╣рдореЗрд╢рд╛ "рдмрд╕ рдПрдХ рдФрд░ рд╕реНрддрд░" рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рджреВрд╕рд░реЗ @benlesh рдХреЗ рд▓рд┐рдП рд╣рдо рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░

рдореИрдВ ppipe рдХрд╛ рд▓реЗрдЦрдХ RXJS рдореЗрдВ рдкрд╛рдЗрдк рдлрд╝рдВрдХреНрд╢рди рдХреА рддрд░рд╣, рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдпрд╣рд╛рдВ рдПрдХ рдкреИрдЯрд░реНрди рджрд┐рдЦрд╛рдИ рджреЗ рд░рд╣рд╛ рд╣реИ ^^

рдореИрдВ runtypes рдХрд╛ рд▓реЗрдЦрдХ

https://github.com/pelotom/runtypes/blob/master/src/types/union.ts

рдореИрдВ

рдореИрдВ ramda рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ pipe , рд▓реЗрдВрд╕ рдФрд░ рдХрд░реАред
рд╣рдореЗрдВ рдХреЛрдбреЗрдЬрди рдХреА рдЬрд░реВрд░рдд рдереА рдХреНрдпреЛрдВрдХрд┐ рдХрд░реА рд╕реАрдзреЗ рдУрд╡рд░рд▓реЛрдб рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рдереАред рд╣рдорд╛рд░рд╛ path рдкреНрд░рдХрд╛рд░ рдПрдХ рд╣рдЬрд╛рд░ рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдлреИрд▓рд╛ рд╣реБрдЖ рд╣реИ, рдЬрд┐рд╕ рдмрд┐рдВрджреБ рдкрд░ рд╣рдордиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдУрд╡рд░рд▓реЛрдб рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рднреА рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЧрдпрд╛ рдерд╛ред

рдХреНрдпрд╛ рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╣реЛ рдЧрдпрд╛ рд╣реИ?

function example(head: string, ...tail: number[]): number[] {
  return [Number(head), ...tail]
}

function apply<T, U>(fn: (...args: T) => U, args: T): U {
  return fn.apply(null, args)
}

рдореЗрдВ рдЯреА рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реИрдВ apply(example, ['0', 1, 2, 3]) рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рди рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ [string, number[]] , рдХреЙрд▓ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрдард╛рдПрдВрдЧреЗред

рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЯреА рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣реИ

type T = [string, ...number[]]

рдпрд╛

type T =
  {0: string} &
  {[key: Exclude<number, 0>]: number} &
  Methods

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЕрдЬреАрдм рдЬрд╛рдирд╡рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ ({0: string} & Array<number>)[0] рд╣реЛрдЧрд╛
рд╡рд░реНрддрдорд╛рди рдореЗрдВ string [1] рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рддрд╛ рд╣реИ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрджрд▓рд╛рд╡ рдХреЗ рдПрдиреНрдХреЛрдб рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ
рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдПред

[рез] рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдмрдЧ рд╣реИ, рдХреНрдпрд╛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ string | number рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ 36 рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЛ рдкрд░реЗрд╢рд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдХрд░реЗрдВ (рдЯрд┐рдк: рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ), рд▓реЗрдХрд┐рди рд╣рдо рдХреИрд╕реЗ рдирд┐рдЧрд░рд╛рдиреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рдкрд░ рдЕрднреА рднреА рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдпрджрд┐ рдпрд╣ рд░реЛрдбрдореИрдк рдкрд░ рд╣реИ, рдЖрджрд┐?

рдпрд╣ рджреБрдЦ рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рдврд╛рдИ рд╕рд╛рд▓ рдмрд╛рдж рднреА рдЗрд╕реЗ рдХрд┐рд╕реА рдХреЛ рдирд╣реАрдВ рд╕реМрдВрдкрд╛ рдЧрдпрд╛, рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИ :(

рдкреАрдПрд╕: рдореИрдВрдиреЗ рджреЛ рджрд░реНрдЬрди рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдкрдврд╝реА рд╣реИрдВ, рд╕реАрдПрдордбреА + рдПрдл рдЖрджрд┐ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рдорд┐рд▓реАред

@brunolemos рдирд╡реАрдирддрдо рдбрд┐рдЬрд╝рд╛рдЗрди рдореАрдЯрд┐рдВрдЧ рдореЗрдВ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдВрджрд░реНрдн рд╣реИ
https://github.com/Microsoft/TypeScript/issues/23045
рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдкрд╣рд▓реЗ рдФрд░ рдЕрдзрд┐рдХ рдЖрджрд┐рдо рдФрд░ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд░реВрдк рд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЬрдм рдкрд░реНрдпрд╛рдкреНрдд рдиреАрдВрд╡ рд╣реЛрдЧреА рддреЛ рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рд╡реЗ рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рдореАрд▓ рдХреЗ рдкрддреНрдерд░ рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ

рдореИ рдРрд╕рд╛ рдирд╣реА рдХрд░ рд╕рдХрддрд╛

type Last<T extends any[]> =
    T extends [infer P] ? P :
    ((...x: T) => any) extends ((x: any, ...xs: infer XS) => any) ? Last<XS> :

#14174 рдХреА рдмрд╛рдд рд╣реИ рд▓реЗрдХрд┐рди рдПрдХ рд░рд┐рд╢реНрддреЗ рдХреЗ рд░реВрдк рдореЗрдВ

@kgtkr рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП @fightingcat рдХреЗ рджреЗрдЦрдиреЗ рдЪрд╛рд▓ рдкреНрд░рддреНрдпрд╛рд╡рд░реНрддрди рдХреА рдЕрдирджреЗрдЦреА рд╕рдВрдХрд▓рдХ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

рдзрдиреНрдпрд╡рд╛рдж

type Last<T extends any[]> = {
    0: never,
    1: Head<T>,
    2: Last<Tail<T>>,
}[T extends [] ? 0 : T extends [any] ? 1 : 2];

рд╣рдореНрдо, рдореЗрд░рд╛ рдПрдХ рдкреНрд░рд╢реНрди рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рдорд┐рд╢реНрд░рдгреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рдХреЛрдб рд╣реИ:

export const Mixed = <

    OP = {}, OS = {}, // base props and state
    AP = {}, AS = {}, // mixin A props and state
    BP = {}, BS = {}, // mixin B props and state
    // ...and other autogenerated stuff
>(

    // TODO: Find a way to write that as ...args with generics:
    a?: ComponentClass<AP, AS>,
    b?: ComponentClass<BP, BS>,
    // ...and other autogenerated stuff

) => {

    type P = OP & AP & BP;
    type S = OS & AS & BS;
    const mixins = [a, b];

    return class extends Component<P, S> {
        constructor(props: P) {
            super(props);
            mixins.map(mix => {
                if (mix) {
                    mix.prototype.constructor.call(this);
                    // some state magic...
                }
            });
        }
    };
};

рдореИрдВ рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ:

class SomeComponent extends Mixed(MixinRedux, MixinRouter, MixinForm) {
     // do some stuff with mixed state
}

рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ - рдЙрдЪрд┐рдд рдЯрд╛рдЗрдкрд┐рдВрдЧ, рд╕реНрдЯреЗрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдЗрддреНрдпрд╛рджрд┐ рдХреЗ рд╕рд╛рде, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рддрд░реАрдХреЗ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реИ? рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЕрднреА рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЧреВрдВрдЧрд╛ рдорд╣рд╕реВрд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

3.0 рдХреЗ рд╕рд╛рде рдЕрдм рдмрд╛рдХреА рдЖрд░реНрдЧ рдХреЛ рдЯрдкрд▓ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ

declare function foo(...args: [number, string, boolean]): void;

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рджрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ?

Arguments<foo> рдЬреИрд╕рд╛ рдХреБрдЫ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

@whitecolor рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?

type Arguments<F extends (...x: any[]) => any> =
  F extends (...x: infer A) => any ? A : never;

TS 3.0 рдХреЗ рд╕рд╛рде рд╣рдо рдЗрд╕реЗ рдЕрднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

function compose<X extends any[], Y extends any[], Z extends any[]>(
  f: (...args: X) => Y,
  g: (...args: Y) => Z
): (...args: X) => Z {
  return function (...args) {
    const y = f(...args);
    return g(...y);
  };
}

рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЫреЛрдЯреА рд╕реА рд╕рдорд╕реНрдпрд╛ рд╣реИ, рд╣рдореЗрдВ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдиреА рд╣реИ рдЬреЛ рдПрдХрд▓ рдкреИрд░рд╛ рдХреЗ рд▓рд┐рдП рдЯреБрдкрд▓реНрд╕ рдИрд╡реЗрдВрдЯ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╢реВрдиреНрдп рд╕реЗ рдирд┐рдкрдЯрддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЕрдиреНрдпрдерд╛ рдЗрд╕реЗ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ :)

https://www.typescriptlang.org/play/index.html#src =%0D%0A%0D%0A%0D%0A%0D%0A%0D%0A%0D%0A%0D%0Afunction%20foo0() %3A%20void%20%7B%0D%0A%20%0D%0A%7D%0D%0A%0D%0Afunction%20bar0()%3A%20void%20%7B%0D%0A%0D%0A%7D %0D%0A%0D%0Afunction%20foo1(a%3A%20string)%3A%20%5Bstring%5D%20%7B%0D%0A%20%20return%20%5Ba%5D%3B%0D%0A% 7D%0D%0A%0D%0Afunction%20bar1(a%3A%20string)% 3A% 20% 5Bstring% 5D% 20% 7B% 0D% 0A% 20% 20 рд░рд┐рдЯрд░реНрди% 20% 5Ba% 5D% 3B% 0D% 0A %7D%0D%0A%0D%0Afunction%20foo2(a1%3A%20string%2C%20a2%3A%20boolean)%3A%20%5Bstring%2C%20boolean%5D%20%7B%0D%0A%20% 20рд╡рд╛рдкрд╕реА%20%5рдмреАрдП1%2рд╕реА%20рдП2%5рдбреА%3рдмреА%0рдбреА%0рдП%7рдбреА%0рдбреА%0рдП%0рдбреА%0рдПрдлрдВрдХреНрд╢рди%20foo21(a1%3A%20string%2C%20a2%3A%20boolean)%3A%20%5Bstring % 5D% 20% 7B% 0D% 0A% 20% 20 рд╡рд╛рдкрд╕реА% 20% 5Ba1% 5D% 3B% 0D% 0A% 7D% 0D% 0A% 0D% 0A% 0D% 0A рдлрд╝рдВрдХреНрд╢рди% 20bar2 (a1% 3A% 20string% 2C) % 20a2% 3A% 20boolean)% 3A% 20% 5Bstring% 2C% 20boolean% 5D% 20% 7B% 0D% 0A% 20% 20 рд╡рд╛рдкрд╕реА% 20% 5Ba1% 2C% 20a2% 5D% 3B% 0D% 0A% 7D% 0D%0A%0D%0A%0D%0Afunction%20compose%3CX%20extend%20any%5B%5D%2C%20Y%20extend%20any%5B%5D%2C%20Z%20extend%20any%5B%5D%3E( %0D%0A%20%20f%3A%20(... args% 3A% 20X)% 20% 3D% 3E% 20Y% 2C% 0D% 0A% 20% 20g% 3A% 20 (... args% 3A% 20Y)% 20% 3D% 3E% 20Z% 0D% 0A )% 3A% 20 (... args% 3A% 20X)% 20% 3D% 3E% 20Z% 20% 7B% 0D% 0A% 20% 20 рд╡рд╛рдкрд╕реА% 20 рдлрд╝рдВрдХреНрд╢рди% 20 (... args)% 20% 7B% 0рдбреА%0рдП%20%20%20%20const%20y%20%3D%20f(...args)%3B%0D%0A%20%20%20return%20g(...y)%3B% 0D%0A% 20% 20% 7D% 3B% 0D% 0A% 7D% 0D% 0A% 0D% 0A% 0D% 0A% 0D% 0A% 0D% 0Aconst% 20baz0% 20% 3D% 20compose(%0D%0A %20%20foo0%2C%0D%0A%20%20bar0%0D%0A)%3B%0D%0A%0D%0Aconst%20baz21%20%3D%20compose(%0D%0A%20%20foo21%2C%0D %0A%20%20bar1%0D%0A)%3B%0D%0Aconst%20baz2%20%3D%20compose(%0D%0A%20%20foo2%2C%0D%0A%20%20bar2%0D%0A)% 3B%0D%0A%0D%0A%0D%0Alert(baz2('a'%2C%20false))%0D%0Alert(baz21('a'%2C%20true))%0D%0Alert(baz0())

@maciejw
рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

function compose<X extends any[], Y extends any, Z extends any>(
  f: (...args: X) => Y,
  g: Y extends any[] ? (...args: Y) => Z : () => Z
): (...args: X) => Z {
    return function (...args) {
        const y = (f as any)(...args);
        return (g as any)(...y);
    } as any;
}

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд▓реЗрдХрд┐рди рдпрд╣ рдЙрди as any рд╕рд╛рде рд╣реИрдХреА рд╣реИ :) рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдмрд┐рдирд╛ рд╣реИрдХреНрд╕ рдХреЗ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ

рдареАрдХ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХрдИ рдЪреАрдЬреЗрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЖрдк рдЗрд╕рдХреЗ рдмрдЬрд╛рдп (f as (...args: any[]) => Y) рдЬреИрд╕рд╛ рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░рдг рдХреЗ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИ

рдпрджрд┐ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдкреНрд░рдХрд╛рд░ рд╕рд╛рдордиреЗ рдЖрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдХреБрдЫ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рдЬрд╛рдКрдВрдЧрд╛ рдЬреЛ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдерд╛, рдЬреЛ рдореБрдЭреЗ рдЕрдкрдиреЗ рдЖрд░рдИрдПрд╕рдЯреА рдПрдкреАрдЖрдИ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЙрд╕ рдЖрдХрд╛рд░ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдиреЛрдб рд╕рд░реНрд╡рд░ рдФрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реАред

рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдЬреЛ рдореБрдЭреЗ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рд╕рд╛рде рд╣реА рдордирдорд╛рдиреА рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░реЗрдЧрд╛, рдФрд░ рдЖрдЧреЗ рдЬрд╛рдХрд░ рдЕрдиреНрдп рднрд╛рд╖рд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рд╕реНрд╡реИрдЧрд░ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдВ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ ... рджреВрд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ! рд╣рд╛рд╣рд╛рд╣рд╛ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЬреЛрд░ рд╕реЗ рд╕рдкрдиреЗ рджреЗрдЦрдирд╛

рдореИрдВ рдкрд╛рдЗрдк рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдореЗрдВ рд╕рдлрд▓ рд░рд╣рд╛
https://github.com/kgtkr/typepark/blob/master/src/pipe.ts

@kgtkr : рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ! :)

рдкрд╛рдЗрдк рдкреНрд░рдХрд╛рд░ рдореЗрд░реЗ рд▓рд┐рдП рдЯреАрдПрд╕ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдиреНрдп рдареАрдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ), рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдирд╡реАрдирддрдо рдЯреАрдПрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

рдЯреАрдПрд╕ рдХреБрдЫ рд░рд┐рдХрд░реНрд╕рди рдЧрд╣рд░рд╛рдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рднреА рджрд┐рдЦрд╛рддрд╛ рд╣реИ - рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @isiahmeadows рдиреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП # 26980 рдЦреЛрд▓рд╛ред

@ tycho01

рдкрд╛рдЗрдк рдкреНрд░рдХрд╛рд░ рдореЗрд░реЗ рд▓рд┐рдП рдЯреАрдПрд╕ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдиреНрдп рдареАрдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ), рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдирд╡реАрдирддрдо рдЯреАрдПрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рднреА рд▓рдЯрдХрд╛ рд╣реБрдЖ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЗрд╕реЗ рддреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП devtools рдореЗрдВ рд╣реИрдХ рдХрд░рдирд╛ рдкрдбрд╝рд╛ред

рдЯреАрдПрд╕ рдХреБрдЫ рд░рд┐рдХрд░реНрд╕рди рдЧрд╣рд░рд╛рдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рднреА рджрд┐рдЦрд╛рддрд╛ рд╣реИ - рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @isiahmeadows рдиреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП # 26980 рдЦреЛрд▓рд╛ред

рдпрд╣ рдХреБрдЫ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдЕрд▓рдЧ рд╣реИ: рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рджреЛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдмрд╛рдзрд╛ рдЙрдард╛рдирд╛:

  • рд╕реВрдЪреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЬреИрд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдп рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдпрд╣ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдХреНрд░реИрд╢ рдХрд┐рдП рдмрд┐рдирд╛ рдпрд╛ рдХреБрдЫ рдПрдб-рд╣реЙрдХ рдореЗрд╕ рдореЗрдВ рд╕рдорд╛рдкреНрдд рдХрд┐рдП рдмрд┐рдирд╛ рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рдЗрдВрдЯреАрдЬрд░ рдореИрде рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХреЛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд░реВрдкрд░реЗрдЦрд╛ рддреИрдпрд╛рд░ рдХрд░реЗрдЧрд╛ред
  • рдЯреАрдПрд╕ рдХреЗ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЯреНрдпреВрд░рд┐рдВрдЧ-рдкреВрд░реНрдг рдмрдирд╛рдиреЗ рдХреЗ рдореБрджреНрджреЗ рдХреЛ рдЕрдзрд┐рдХ рдареАрдХ рд╕реЗ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдпрд╛ рддреЛ рдЗрд╕рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рд╕рдбрд╝рдХ рдХреЗ рдиреАрдЪреЗ рд╕рд╛рдмрд┐рдд рд╣реЛрдиреЗ рдпреЛрдЧреНрдп рд╕рдорд╛рдкреНрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрджрд┐ рдЕрдиреБрдХреНрд░рдорд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЯреНрдпреВрд░рд┐рдВрдЧ-рдкреВрд░реНрдг рдирд╣реАрдВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рд╡рд╣рд╛рдВ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдореИрдВ рдЗрд╕реЗ рддрджрдиреБрд╕рд╛рд░ рдЕрдкрдбреЗрдЯ рдХрд░ рд╕рдХреВрдВред (рдореИрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕реЗ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдирд╣реАрдВ рдХрд░рддрд╛ред рдореИрдВ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдирдВрдд рд▓реВрдк рдХреЗ рд▓реЛрдЧреЛрдВ рдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред)

рджреВрд╕рд░реЗ рд╡рд┐рдЪрд╛рд░ рдкрд░, рдпрд╣ рдкрд╛рдЗрдк рдкреНрд░рдХрд╛рд░ (vs...: Params<T[0]>) => ReturnType<Last<T>> рдХрд░рдиреЗ рдХрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрдЯрд┐рд▓ рддрд░реАрдХрд╛ рд▓рдЧрддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдкрд░реЗ рдХреЛрдИ рднреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ (рдордзреНрдпрд╡рд░реНрддреА рдкрд░рдо рдЪреЗрдХ рд╕реЗ рдЕрд▓рдЧ) рд╢рд╛рдпрдж рдЗрдирдкреБрдЯ-рдирд┐рд░реНрднрд░ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рд╣реЛ рдЬрд╛рддреА рд╣реИред

@ tycho01 рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЛрдВ рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдкреНрд░рдХрд╛рд░ рдореВрд▓ рд░реВрдк рд╕реЗ рдпрд╣ рд╣реИ:

   f1,     f2,   ...,   fm,     fn    -> composed
(a -> b, b -> c, ..., x -> y, y -> z) -> (a -> z)

рдЖрдк рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЗрд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЗ рдмрд╛рдж рд╕реЗ рдмрд╛рдж рдХреЗ рдорд╛рдирдХреЛрдВ рд╡рд╛рдкрд╕реА рдорд╛рди 'рдорд╛рдирдХреЛрдВ рдкрд┐рдЫрд▓реЗ рдорд╛рдирдХреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ', рдФрд░ рдЖрдк рднреА рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдЕрдВрдд рд╡рд╛рдкрд╕реА рдорд╛рди рдХреЗ рд▓рд┐рдП рдЦрд╛рддреЗ рдореЗрдВ рд░рд╛рд╢рд┐ (рд░реЛрдВ рдЬреЛ @kgtkr 'рдирд╣реАрдВ рд╣реИ) . # 26980 рдореЗрдВ рдореЗрд░реЗ "рдмреЗрд╣рддрд░" рд╕рдВрд╕реНрдХрд░рдг рдиреЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд╕рдВрдЪрдпрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рддрд░реНрдХреЛрдВ рдХреЛ рдмрд╣реБрдд рдХрдо рдХрд░ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдиреЗ рдЗрд╕реЗ рдФрд░ рднреА рд╕рд╣реА рдмрдирд╛ рджрд┐рдпрд╛ред


рдпрджрд┐ рдЖрдк #реиремрепреореж рдореЗрдВ рдореЗрд░рд╛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдереЛрдбрд╝рд╛ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдХрдо рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдкреАрдЫрд╛ рдХрд░рдирд╛), рдФрд░ рдпрд╣ рдЗрд╕ рдмрд╛рдд рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЙрд╕ рд╕реБрд╡рд┐рдзрд╛ рдЕрдиреБрд░реЛрдз рдХреЛ рдХреНрдпреЛрдВ рджрд╛рдпрд░ рдХрд┐рдпрд╛ред

@ tycho01 @kgtkr BTW, рдореИрдВрдиреЗ рдЙрд╕ рдмрдЧ рдХреЛ рдПрдХ рд╕рд╣реА PipeFunc рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд╕рд╛рде рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

type Last<L extends any[], D = never> = {
    0: D,
    1: L extends [infer H] ? H : never,
    2: ((...l: L) => any) extends ((h: any, ...t: infer T) => any) ? Last<T> : D,
}[L extends [] ? 0 : L extends [any] ? 1 : 2];

type Append<T extends any[], H> =
    ((h: H, ...t: T) => any) extends ((...l: infer L) => any) ? L : never;

type Reverse<L extends any[], R extends any[] = []> = {
    0: R,
    1: ((...l: L) => any) extends ((h: infer H, ...t: infer T) => any) ?
        Reverse<T, Append<R, H>> :
        never,
}[L extends [any, ...any[]] ? 1 : 0];

type Compose<L extends any[], V, R extends any[] = []> = {
    0: R,
    1: ((...l: L) => any) extends ((a: infer H, ...t: infer T) => any) ?
        Compose<T, H, Append<R, (x: V) => H>>
        : never,
}[L extends [any, ...any[]] ? 1 : 0];

export type PipeFunc<T extends any[], V> =
    (...f: Reverse<Compose<T, V>>) => ((x: V) => Last<T, V>);

рдпрд╣ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдореЗрдВ рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, BTWред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЯрд╛рдЗрдк-рдЪреЗрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдмрд╣реБрдд рдЬрд▓реНрджреА рдХрд░рддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдЕрднреА рддрдХ рд╕рдВрднрд╛рд╡рд┐рдд _.flow рдпрд╛ _.flowRight рдкреНрд░рдХрд╛рд░ рдкрд░ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

@ tycho01
рдЖрд╡рд╢реНрдпрдХ
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ@рдЕрдЧрд▓рд╛
3.0.1/3.0.2 рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛

рдЗрд╕ рд╕реВрддреНрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рдмрдирд╛ рдпрд╣

рд▓реЛрдЧ, рдХреГрдкрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдкреЛрд╕реНрдЯ рдХрд░рдирд╛ рдмрдВрдж рдХрд░реЗрдВред рдЗрд╕ рдЪрд░реНрдЪрд╛ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдореБрдЭреЗ рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рджрд┐рдиреЛрдВ рдореЗрдВ рдРрд╕реЗ резреж+ рдИрдореЗрд▓ рдкреНрд░рд╛рдкреНрдд рд╣реБрдП рд╣реИрдВ рдЬреЛ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИрдВред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдореЗрд░реЗ рд╕рд╛рде рдЕрдиреНрдп рд▓реЛрдЧ рднреА рд╕рд╣рдордд рд╣реЛрдВрдЧреЗред рдЕрдм рддрдХ рдореБрдЭреЗ рдмрд╕ рдпрд╣реА рдЙрдореНрдореАрдж рдереА рдХрд┐ рдпрд╣ рд░реБрдХ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рд╕реНрдкреИрдо рдореЗрдВ рдпреЛрдЧрджрд╛рди рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдЧрдВрднреАрд░рддрд╛ рд╕реЗ, рдХрд╛рдлреА рд╣реИред
рдкреАрдПрд╕ рдЗрд╕ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ, рдЬреЛ рдХреЛрдИ рднреА рдЙрдирд╕реЗ рдмреАрдорд╛рд░ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╣реВрдВ

@Yuudaari рдореИрдВ _.flow , Ramda рдХрд╛ _.compose , рдЖрджрд┐ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЗрд╕ рдмрдЧ рдХреЗ рд▓рд┐рдП рдбреНрд░рд╛рдЗрд╡рд┐рдВрдЧ рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдФрд░ рдПрдХ рд╕рдлрд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдореВрд▓ рд╕рдорд╕реНрдпрд╛ рд╡рд┐рд╡рд░рдг рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд╛рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдореЗрд░реА рд░рд╛рдп рд╣реИ рдХрд┐ 99% рд╕рдорд╕реНрдпрд╛рдПрдВ рдЬреЛ рдЖрдЬ рд╡реИрд░рд┐рдПрдбрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рдореМрдЬреВрдж рд╣реИрдВ, рдПрд░реНрдЧреЛрдиреЙрдорд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рд╣реИрдВ, рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдирд╣реАрдВред рд╣рдо рдЯрд╛рдЗрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ Function.prototype.bind рдФрд░ Promise.all рдЕрдиреБрдХреНрд░рдорд┐рдд рдкреНрд░рдХрд╛рд░, рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░, рдФрд░ рдкреНрд░рддреНрдпрд╛рд╡рд░реНрддрди рдХрд╛ рдПрдХ рдорд┐рд╢реНрд░рдг рдХреЗ рд╕рд╛рде рдкреВрд░реА рддрд░рд╣ (рдпрджрд┐ рдЖрдк рдПрдХ рдмрд╛рд░-рдмрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ Append рдХреЗ рд▓рд┐рдП рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реВрдЪреА Function.prototype.bind , рдФрд░ Promise.all рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╣реЛрдЧреА + Append ), рдмрд╕ рдРрд╕рд╛ рдХрд░рдирд╛ рдмрд╣реБрдд рдЕрдЬреАрдм рдФрд░ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯреА рд╣реИред

рдпрд╣рд╛рдВ рд╢реЛрд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдХреЗрд╡рд▓ рдпрд╣ рд╕рдордЭрд╛рддреЗ рд╣реБрдП рдХрд┐ рдпрд╣рд╛рдВ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдЪреАрдЬреЗрдВ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рд╡рд┐рд╖рдп рдкрд░ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрдЧ рдореМрдЬреВрдж рд╣реЛрдиреЗ рдХреЗ рдХреБрдЫ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ, рднрд▓реЗ рд╣реА рд╡реЗ рд╡реЗ рдирд╣реАрдВ рд╣реИрдВ рдЬрд┐рдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЪрд┐рдВрддрд┐рдд рд╣реИрдВред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдШреЛрд╖рдгрд╛рдУрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд▓реЛрдЧреЛрдВ рдиреЗ рдмрдбрд╝реА рдЦрдмрд░ рдХреЛ рдпрд╛рдж рдХрд┐рдпрд╛ - рдпрд╣ рдЕрдм рд╕рдВрднрд╡ Concat<T, U> рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдмрд┐рд▓реНрдХреБрд▓ [...T, ...U] ред

Pipe рдЙрдк-рдереНрд░реЗрдб рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдпрд╣рд╛рдВ рдорд╛рдВрдЧреА рдЧрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред рдпрд╣ рдЖрдЬ рдЗрд╕ рд╕реВрддреНрд░ рдХреЗ рдмрд┐рдВрджреБ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рдзрд╛рдЧреЗ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рднреА рдмрджрддрд░ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рд╢рд╛рдпрдж рдпрд╣ рдкреВрдЫрдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдХреНрд╖рдг рд╣реИ - рд▓реЛрдЧ рдЕрднреА рднреА рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

[рдпрд╣] рдмрд╕ рдпрд╣ рдмрд╣реБрдд рд╣реА рдЕрдЬреАрдм рдФрд░ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯреА рд╣реИ

рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкреНрд░рдХрд╛рд░ рд╕реНрд╡рдпрдВ рдкреБрдирд░рд╛рд╡рд░реНрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдирд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдВрдЧреЗ, рдЬрдмрдХрд┐ рдЕрдВрддрд┐рдо-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдВрднрд╡рддрдГ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЯреАрдПрд╕ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рдЬрд╛рдиреЗ рдмрд┐рдирд╛ рдЕрдкрдиреЗ рдлреНрд░рдВрдЯ-рдПрдВрдб рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред

рдЙрд╕ рд╕рдордп рд╢рд╛рдпрдж рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рдЕрдзрд┐рдХрддрд░ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдорд╛рдирдЪрд┐рддреНрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд░рд┐рдХрд░реНрд╕рди рдХрд░рдиреЗ рдХреЗ рдЗрд░рд╛рджреЗ рд╕реЗ рднреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд░рд╣рд╛ рд╣реИ? рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ (рдореИрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ), рддреЛ рдХреНрдпрд╛ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдЯреВрдЯрдиреЗ рдХреЗ рдЕрдзреАрди рдирд╣реАрдВ рд╣реЛрдЧрд╛?

рджреВрд╕рд░реЗ, рдЗрди рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдареАрдХ рдирд╣реАрдВ рд╣реИ... рдорд┐рддреНрд░рд╡рддред рдпрд╣ рдмрд╣реБрдд рдкрдардиреАрдп рдирд╣реАрдВ рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рд╣реИ), рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЗрд╕реЗ рдмрдирд╛рдП рд░рдЦрдирд╛ рджрдпрдиреАрдп рд▓рдЧрддрд╛ рд╣реИред

рдореИрдВ рдПрдХ рдРрд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд░ рд╡рд╛рдкрд╕ рдХреНрдпреЛрдВ рдЖрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рд╕рдорд╛рди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдПрдХ рдЗрдЪреНрдЫрд┐рдд, рдкрдардиреАрдп рдФрд░ рд░рдЦрд░рдЦрд╛рд╡ рдпреЛрдЧреНрдп рддрд░реАрдХреЗ рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рд╕рд┐рд░реНрдл рдЗрд╕рд▓рд┐рдП рдХрд┐ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ?

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рдЪреАрдиреА рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рднреА, рддреЛ рдореИрдВ рдЗрд╕ рдЧрдбрд╝рдмрдбрд╝реА рдХреЗ рд▓рд┐рдП рд╡рд╛рдХреНрдп рд░рдЪрдирд╛рддреНрдордХ рдЪреАрдиреА рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛?

@рдпреБрджрд╛рд░реА

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реЗрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдорд╛рдирдЪрд┐рддреНрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд░рд┐рдХрд░реНрд╕рди рдХрд░рдиреЗ рдХреЗ рдЗрд░рд╛рджреЗ рд╕реЗ рднреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд░рд╣рд╛ рд╣реИ? рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ (рдореИрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ), рддреЛ рдХреНрдпрд╛ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдЯреВрдЯрдиреЗ рдХреЗ рдЕрдзреАрди рдирд╣реАрдВ рд╣реЛрдЧрд╛?

рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рджрд╛рдпрд░ рдХреА рдЧрдИ рдмрдЧ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ: #реиремрепреорежред рдЖрдк рдкреИрдЯрд░реНрди рдкрд░ рд╕рд╡рд╛рд▓ рдЙрдард╛рдиреЗ рд╡рд╛рд▓реЗ рдЕрдХреЗрд▓реЗ рдирд╣реАрдВ рд╣реИрдВред рдпрд╣ рдпрд╣рд╛рдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╡рд┐рд╖рдп рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдВ рдЭрдВрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЧрдгрд┐рдд рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдП рдХрд┐ рдХреНрдпрд╛ рдХреБрдЫ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ (рдореБрдЦреНрдп рдХрд╛рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдпрд╣ рдкрд╣рд▓реА рдЬрдЧрд╣ рдореЗрдВ рдЗрддрдирд╛ рдмрд╛рд░реАрдХ рдХреНрдпреЛрдВ рд╣реИ)ред

рджреВрд╕рд░реЗ, рдЗрди рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдареАрдХ рдирд╣реАрдВ рд╣реИ... рдорд┐рддреНрд░рд╡рддред рдпрд╣ рдмрд╣реБрдд рдкрдардиреАрдп рдирд╣реАрдВ рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рд╣реИ), рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЗрд╕реЗ рдмрдирд╛рдП рд░рдЦрдирд╛ рджрдпрдиреАрдп рд▓рдЧрддрд╛ рд╣реИред

рдореИрдВ рдПрдХ рдРрд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд░ рд╡рд╛рдкрд╕ рдХреНрдпреЛрдВ рдЖрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рд╕рдорд╛рди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдПрдХ рдЗрдЪреНрдЫрд┐рдд, рдкрдардиреАрдп рдФрд░ рд░рдЦрд░рдЦрд╛рд╡ рдпреЛрдЧреНрдп рддрд░реАрдХреЗ рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рд╕рд┐рд░реНрдл рдЗрд╕рд▓рд┐рдП рдХрд┐ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ?

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рдЪреАрдиреА рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рднреА, рддреЛ рдореИрдВ рдЗрд╕ рдЧрдбрд╝рдмрдбрд╝реА рдХреЗ рд▓рд┐рдП рд╡рд╛рдХреНрдп рд░рдЪрдирд╛рддреНрдордХ рдЪреАрдиреА рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛?

рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ Array.prototype.map рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рдореЗрдВ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд░рд▓ рддрд░реАрдХрд╛ рдореМрдЬреВрдж

рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЗрдирдХреЗ рд▓рд┐рдП рд╡рд╛рдХреНрдп рд░рдЪрдирд╛рддреНрдордХ рдЪреАрдиреА рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛:

  1. [...First, ...Second] рдорд╛рдзреНрдпрдо рд╕реЗ рджреЛ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ред
  2. [...Values, Item] рдорд╛рдзреНрдпрдо рд╕реЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ред
  3. T extends [...any[], infer Last] рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдВрддрд┐рдо рддрддреНрд╡ рдирд┐рдХрд╛рд▓рдирд╛ред
  4. T extends [A, B, ...infer Tail] рдорд╛рдзреНрдпрдо рд╕реЗ рдкреВрдВрдЫ рдирд┐рдХрд╛рд▓рдирд╛ред

рдЗрд╕реЗ #26980 рдХреЗ рд╕рд╛рде рдорд┐рд▓рд╛рдПрдВ, рдФрд░ рдореИрдВ рдЙрдкрд░реЛрдХреНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЗрд╕рдореЗрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реВрдВ:

type Compose<L extends any[], V, R extends any[] = []> =
    L extends [infer H, ...infer T] ?
        Compose<T, H, [...R, (x: V) => H]> :
        R;

export type PipeFunc<T extends any[], V> =
    T extends [...any[], infer R] ?
        (...f: Compose<T, V>) => ((x: V) => R) :
        () => (x: V) => V;

рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдореБрдЭреЗ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рдЪреАрдиреА рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рджрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣рд╛рдВ рдЕрдзрд┐рдХрддрд░ рд╕рдм рдХреБрдЫ рд╕рд┐рд░реНрдл рдЯреБрдкрд▓реНрд╕ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ, рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдЖрдкрдХреЛ рд╕рдорд╛рди рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдХрднреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдорд╛рдирдЪрд┐рддреНрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд░рд┐рдХрд░реНрд╕рди рдХрд░рдиреЗ рдХреЗ рдЗрд░рд╛рджреЗ рд╕реЗ рднреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд░рд╣рд╛ рд╣реИ? рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ (рдореИрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ), рддреЛ рдХреНрдпрд╛ рдпрд╣ рдмрд╛рдж рдореЗрдВ рдЯреВрдЯрдиреЗ рдХреЗ рдЕрдзреАрди рдирд╣реАрдВ рд╣реЛрдЧрд╛?

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╢рдмреНрдж "рдРрд╕рд╛ рдордд рдХрд░реЛ" рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реИред @ahejlsberg рдиреЗ рдХрд╣рд╛ :

рдпрд╣ рдЪрддреБрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЪреАрдЬреЛрдВ рдХреЛ рдЙрдирдХреЗ рдЗрдЪреНрдЫрд┐рдд рдЙрдкрдпреЛрдЧ рд╕реЗ рдкрд░реЗ рдзрдХреЗрд▓рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЫреЛрдЯреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛ред рдЙрди рдЧрд╣рди рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рдФрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЦрдкрдд рд╣реЛрддреА рд╣реИ рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЪреЗрдХрд░ рдореЗрдВ рдореМрдЬреВрдж рд░рд┐рдХрд░реНрд╕рди рдЧрд╡рд░реНрдирд░реНрд╕ рд╕реЗ рджреВрд░ рднрд╛рдЧ рд╕рдХрддреЗ рд╣реИрдВред

рдордд рдХрд░реЛ!

я╕П

@jcalz рддреЛ # 26980 рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рдЖрдиреЗ рдХрд╛ рдФрд░ рднреА рдХрд╛рд░рдг?

рдЬрдм рдореИрдВрдиреЗ рдЗрд╕ рд╕рд╛рд▓ рдХреЗ рдПрдХ рдмреНрд░реЗрдХ рдХреЗ рдмрд╛рдж TS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рддреЛ рдореЗрд░рд╛ рдЭреБрдХрд╛рд╡ _just that_! рд▓рд┐рдЦрдиреЗ рдХрд╛ рдерд╛! ( ...T ) рдЗрд╕ рдЙрдореНрдореАрдж рдореЗрдВ рдХрд┐ рдпрд╣ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЯрд╛рдЗрдкрд╡рд╛рд░ рдЯреБрдкрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╣реЛрдЧрд╛ред рдЦреИрд░, рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдВрджрд░ рдЖ рдЬрд╛рдПрдЧрд╛ :)

[...T, ...U] рд▓рд┐рдП рдмрд╕ рдПрдХ рдирдпрд╛ рдЙрдкрдпреЛрдЧ рдорд┐рд▓рд╛: HTML рдмрд┐рд▓реНрдбрд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдирд╛ред рдПрдХ рдареЛрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, <video> рдХреЗ рдмрдЪреНрдЪреЛрдВ рдХрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реЛрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:

  • рдпрджрд┐ рддрддреНрд╡ рдореЗрдВ src рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ:

    • рд╢реВрдиреНрдп рдпрд╛ рдЕрдзрд┐рдХ <track> рддрддреНрд╡

  • рдпрджрд┐ рддрддреНрд╡ рдореЗрдВ src рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИ:

    • рд╢реВрдиреНрдп рдпрд╛ рдЕрдзрд┐рдХ <source> рддрддреНрд╡

  • рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд╛рдордЧреНрд░реА рдореЙрдбрд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╢реВрдиреНрдп рдпрд╛ рдЕрдзрд┐рдХ рддрддреНрд╡, рд╕рд┐рд╡рд╛рдп audio рдпрд╛ video рд╡рдВрд╢рдЬ рддрддреНрд╡ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред

рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдЬ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЗрд╕реЗ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ:

type VideoChildren<ParentModel extends string[]> = [
    ...Array<"track">, // Not possible
    ...{[I in keyof ParentModel]: P[I] extends "audio" | "video" ? never : P[I]},
]

3.5 рд╕рд╛рд▓ :/

рдЙрджрд╛рд╣рд░рдг:

type DrawOp<...T> = (G: CanvasRenderingContext2D, frame: Bounds, ...args: any[]) => void;
const drawOps: DrawOp<...any>[] = [];

function addDrawOp<...T>(fn: DrawOp<...T>, ...args: T) {
    drawOps.push(fn);
}

рдореИрдВ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдЦреБрд▓реЗ рдкреНрд░рд╢реНрди рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдХреЗрд╡рд▓ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдЕрдзрд┐рднрд╛рд░ рджреЗрдЦрддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдРрд╕рд╛ рдЬреЛ рдореИрдВрдиреЗ рдЪрд▓рд╛рдпрд╛ рд╣реИ рдФрд░ рд╕рдорд╛рдзрд╛рди рдпрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдХреГрд╖реНрдЯ рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

  function $findOne(
    ctx: ICtx,
    filter: FilterQuery<TSchema>,
    cb: Cb<TSchema>,
  ): void;
  function $findOne<T extends keyof TSchema>(
    ctx: ICtx,
    filter: FilterQuery<TSchema>,
    projection: Projection<T>,
    cb: Cb<Pick<TSchema, T>>,
  ): void;
  function $findOne(
    ctx: ICtx,
    filter: FilterQuery<TSchema>,
    projection: undefined,
    cb: Cb<TSchema>,
  ): void;
  function $findOne<T extends keyof TSchema>(
    ctx: ICtx,
    filter: mongodb.FilterQuery<TSchema>,
    projection: Projection<T> | Cb<TSchema> | undefined,
    cb?: Cb<Pick<TSchema, T>>,
  ): void {

  promisify($findOne) // this can't infer types correctly

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ promisify рдХреЛ (ctx: ICtx, filter: FilterQuery<TSchema>) => Promise<TSchema[]> рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрди рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдЦреЛ рд░рд╣рд╛ рд╣реИред

AFAICT рдЗрд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╛рдзрд╛рди рдореВрд▓ рд░реВрдк рд╕реЗ рдПрдХ рд╡рд╛рджрд╛ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдирд╛ рд╣реИ рдФрд░ рдЙрд╕ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реИ - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рд╕рдореНрдорд╛рдирд┐рдд рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рдУрд╡рд░рд▓реЛрдб рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛ рдпрд╣ рдмрддрд╛рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдЙрд╕ рддрд░рд╣ рд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрдирдХреЗ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рддрд░реНрдХреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░рд┐рдЯрд░реНрди рдХреА рдЙрдореНрдореАрдж рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред

рдпрд╣ рдЗрд╕ рддрдереНрдп рд╕реЗ рдмрдврд╝рд╛ рд╣реИ рдХрд┐ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗрд╡рд▓ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдпрд╛рдиреА (cb, ...args) рдорд╛рдиреНрдп рд╣реИ рд▓реЗрдХрд┐рди (...args, cb) , рдЗрд╕рд▓рд┐рдП рднрд▓реЗ рд╣реА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдлреИрд▓рд╛рдПрдВ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реЛрдЧрд╛ рдпрджрд┐ cb рд╣рдореЗрд╢рд╛ function promisify<T, V extends any[]>(fn: (cb: (err: Error | null, res?: T) => void, ...args: V)): (...args: V) => T рд░реВрдк рдореЗрдВ рд╡рд╛рджрд╛ рдХрд░рдиреЗ рдХрд╛ рдкрд╣рд▓рд╛ рддрд░реНрдХ рдерд╛ рдФрд░ рдЖрдк рдХрдо рд╕реЗ рдХрдо рд╕рдорд╛рди рд╡рд╛рдкрд╕реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд▓рд┐рдП рд╕рдВрдШ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рдереЗ, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣рд╛рдВ рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

@Qix- рдЖрдкрдХрд╛ рдкрд░рд┐рджреГрд╢реНрдп #24897 рджреНрд╡рд╛рд░рд╛ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЯреАрдПрд╕ 3.0 рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

@ahejlsberg рдКрдл! рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛, рдзрдиреНрдпрд╡рд╛рдж я╕П

рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реБрдП рдмрд╣реБрдд рд╕рдордп рд╣реЛ рдЧрдпрд╛... рд▓реЗрдХрд┐рди рдЖрдЬ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИред TS рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдкрд░рд┐рдкрдХреНрд╡ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд░рд╛рдорджрд╛ рдХреЗ рд▓рд┐рдП рдХрд░реА, рдХреЙрдирдХреИрдЯ, рдХрдВрдкреЛрдЬрд╝ рдФрд░ рдкрд╛рдЗрдк рдХреЗ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордп рдирд┐рдХрд╛рд▓рд╛ред

рдФрд░ рдЕрдм рдЙрдиреНрд╣реЗрдВ ts-toolbelt рдХреЗ рд╕рд╛рде рднреЗрдЬ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕рд╛рдорд╛рдиреНрдп рдЯрдкрд▓ рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреА рд╡рд╛рдХреНрдпрд╛рддреНрдордХ рдЪреАрдиреА рд╣реИред

рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдорд╛рдзреНрдпрдо.рдХреЙрдо рдкрд░ рд╣реИ? рдпреВрдЖрд░рдПрд▓?

рдорд╛рдзреНрдпрдо рдкрд░ рдореВрд▓ рд▓реЗрдЦ рд╣реИ рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдмреЛрдирд╕ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд░реЗрдкреЛ рдореЗрдВ рд╣реИред рдпрд╣ рдпрд╣ рднреА рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдореИрдВрдиреЗ рд░рдЪрдирд╛, рдкрд╛рдЗрдк рдФрд░ рдХрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЫреЛрдЯреЗ рдЙрдкрдХрд░рдг рдмрдирд╛рдП: рдореБрд╕реНрдХрд╛рди:

@ pirix-gh рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдирд░рд┐рдХ рдирд╣реАрдВ рд╣реИ

declare function m<...T>(): T

m<number, string>() // [number, string]

@goodmind рд╣рд╛рдБ, рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдЕрдзрд┐рдХ рдЕрдиреБрдХрд░рдгреАрдп рд╣реИред рддреЛ рдЖрдк рдЗрд╕ рддрд░рд╣ ... рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

declare function m<T extends any[], U extends any[]>(): Concat<T, U>

m<[number, string], [object, any]>() // [number, string, object, any]

рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рдХрд┐:

declare function m<...T, ...U>(): [...T, ...U]

m<number, string, object, any>() // [number, string, object, any]

рдЗрд╕ рдмреАрдЪ, рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реБрдП :hourglass_flowing_sand:

@ pirix-gh рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рд░реИрдкрд┐рдВрдЧ рдлрдВрдХреНрд╢рди рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ

type fn = <T>(arg: () => T) => T
let test1: fn
let res1 = test1(() => true) // boolean

type fnWrap = (...arg: Parameters<fn>) => ReturnType<fn>
let test2: fnWrap
let res2 = test2(() => true) // {}

рдореИрдВ рд░рдЪрдирд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ рд▓реЗрдХрд┐рди рдЕрд╕рдлрд▓ рд░рд╣рд╛, рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЙрдЪрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рд╕реБрдЭрд╛рд╡ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ?

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдЖрдк рдЬреЗрдирд░рд┐рдХ рдкрд░ рдирд┐рд░реНрднрд░ fn рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░/рд░рд┐рдЯрд░реНрди рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ TS рдЙрдиреНрд╣реЗрдВ рдЙрдирдХреЗ рдирд┐рдХрдЯрддрдо рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ T рд╣реЛрдЧрд╛ any )ред рддреЛ рдлрд┐рд▓рд╣рд╛рд▓ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдорд╛рд░реА рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ https://github.com/Microsoft/TypeScript/pull/30215 рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛

рдпрд╛, рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЬреЗрдирд░рд┐рдХ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕рдВрд░рдХреНрд╖рд┐рдд/рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдвреВрдВрдв рд╕рдХреЗрдВ рдХрд┐ рд╣рдо рдХрд░ рд╕рдХреЗрдВ:

declare function ideal<...T>(a: T[0], b: T[1], c: T[2]): T

ideal('a', 1, {}) // T = ['a', 1, {}]

рдЗрд╕ рддрд░рд╣, рд╣рдо рдЗрд╕рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рд╕реЗ fn рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗред рдЖрдЬ рдЧрд╛рдпрдм рд╣рд┐рд╕реНрд╕рд╛ рд╕рд╛рдорд╛рдиреНрдп рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬреИрд╕реЗ @goodmind рдиреЗ рдмрддрд╛рдпрд╛ред

@ pirix-gh рдЕрдЧрд░ рдореБрдЭреЗ рдЧрд▓рдд рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣реИ:

declare function MyFunction<A, B, C, Args extends [A, B, C]>(...[a, b, c]: Args): Args

const a = MyFunction(1, 'hello', true);
// typeof a = [number, string, boolean]

@ClickerMonkey рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ рдЬреЛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рд╡рд╣ рдЕрд╕реАрдорд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдпрд╣ рднреА рдХрд░ рд╕рдХреЗрдВ, рдЬреЛ рдЖрдкрдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рд╣реИ (рдореИрдВрдиреЗ рдЗрд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИ):

declare function MyFunction<A, B, C, ...Args>(...[a, b, c]: Args): Args

const a = MyFunction(1, 'hello', true);
// typeof a = [number, string, boolean]

@pirix-gh рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ A , B рдФрд░ C рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдЕрдкреНрд░рдпреБрдХреНрдд рд╣реИрдВред

-declare function MyFunction<A, B, C, ...Args>(...[a, b, c]: Args): Args
+declare function MyFunction<...Args>(...[a, b, c]: Args): Args

рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдЕрдЧрд░ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рдереЗ рддреЛ рдкрд┐рдЫрд▓реЗ рджреЛ рдЙрджрд╛рд╣рд░рдг рд╢рд╛рдпрдж рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗ, рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ рддреАрди рддрд░реНрдХ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИред

рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рдкрддрд╛ рдЪрд▓реЗрдЧрд╛ рдХрд┐ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ, рдЕрдЧрд░ рдЙрдиреНрд╣реЗрдВ рдореМрдЬреВрджрд╛ рдЯреАрдПрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддреЛ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

@goodmind рд╣рд╛рдБ, рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдЕрдзрд┐рдХ рдЕрдиреБрдХрд░рдгреАрдп рд╣реИред рддреЛ рдЖрдк рдЗрд╕ рддрд░рд╣ ... рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

declare function m<T extends any[], U extends any[]>(): Concat<T, U>

m<[number, string], [object, any]>() // [number, string, object, any]

рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рдХрд┐:

declare function m<...T, ...U>(): [...T, ...U]

m<number, string, object, any>() // [number, string, object, any]

рдЗрд╕реА рдмреАрдЪ рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рддреЗ рд╣реБрдП

рдЖрдкрдХреЛ Concat<> рдХрд╣рд╛рдВ рд╕реЗ рдорд┐рд▓рд╛?

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╕реНрд░реЛрдд рдХреЛрдб рдХрднреА рдирд╣реАрдВ рдорд┐рд▓рд╛ред

@ pirix-gh рддреЛ рдореИрдВрдиреЗ рдЖрдкрдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╕рдордЭ рдирд╣реАрдВ рдкрд╛рдпрд╛ред

~рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╕реАрдЯреАрдЖрд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдХрдИ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ рд▓реЗрдХрд┐рди рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╕реАрдЯреАрдЖрд░ рдкреИрд░рд╛ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдлреИрд▓рд╛ рд╕рдХрддрд╛ред ~

Class Test {
  constructor(x: number, y: string) {}
}
let ExtendedClass = extendCtor<[number, string], [number]>(Test);

let instance = new ExtendedClass(1, '22', 2);

рдЕрджреНрдпрддрди: рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рдХрд┐ рд╕реАрдЯреАрдЖрд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдкреНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреА рдХрд╛рдо рдХрд┐рдпрд╛ред

рдпреЗ рд░рд╣рд╛ рд╕рдорд╛рдзрд╛рди рдХрд╛ рд▓рд┐рдВрдХ

рдПрдХрдорд╛рддреНрд░ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд▓рдЧрднрдЧ рд╣рд░ рдмрд╛рд░ TS
рдФрд░ рдпрд╣реА рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╣рддрд╛ рд╣реИ Type instantiation is excessively deep and possibly infinite.ts(2589)

рдЕрдкрдбреЗрдЯ 2:
рдореИрдВрдиреЗ рдЗрд╕реЗ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЛ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдбрд╛рд▓рдХрд░ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛, рдлрд┐рд░ рднреА рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдорд░реНрдЬ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред

// ...
type CtorArgs<T, X> = T extends (new (...args: infer U) => any) ? [...U, X] : never;
// To be used as CtorArgs<typeof Test, string>
// ...
let instance = new MyClass1('22', 2, 'check');

рд╡рд┐рд░реЛрдз рдХреЗ рд░реВрдк рдореЗрдВ:

let MyClass1 = extendClass<typeof Test, string>(Test);

let instance = new MyClass1('check', '22', 2);

рдЕрдВрддрд┐рдо рд╕рдорд╛рдзрд╛рди рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ ред

рдЕрдЧрд░ рдореИрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ рддреЛ Object.assign рдХреЛ рд╡рд┐рднрд┐рдиреНрди рддрд░реНрдХреЛрдВ рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рдХреБрдЫ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

type Assign<T, U extends any[]> = {
  0: T;
  1: ((...t: U) => any) extends ((head: infer Head, ...tail: infer Tail) => any)
    ? Assign<Omit<T, keyof Head> & Head, Tail>
    : never;
}[U['length'] extends 0 ? 0 : 1]

interface ObjectConstructor {
  assign<T, U extends any[]>(target: T, ...source: U): Assign<T, U>
}

рдХреНрдпрд╛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ lib.d.ts рдореЗрдВ рдЗрд╕реЗ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рд╣реИ?

рдпрд╣ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИрдВ (рдЙрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП # 26980 рджреЗрдЦреЗрдВ, рдпрд╛ рдпрд╣ рдЯрд┐рдкреНрдкрдгреА рд╣рдореЗрдВ рдРрд╕рд╛ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд░рд╣реА рд╣реИ)ред рдпрджрд┐ рдХреЛрдИ рд╡рд░реНрддрдорд╛рди рдЪреМрд░рд╛рд╣реЗ рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЛ рддреИрдпрд╛рд░ рд╣реИ рддреЛ #28323 рд╣реИред

@jcalz рдореИрдВрдиреЗ рдПрдХ рднрд╛рд░реА рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдпрд╛ рдЬреЛ Minus рдкреНрд░рдХрд╛рд░ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдпрд╣ 4 рд╕реЗрдХрдВрдб рд╕реЗ рднреА рдХрдо рд╕рдордп рдореЗрдВ Minus 216000 рдмрд╛рд░ рдкреНрд░рджрд░реНрд╢рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ TS рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╣рд╛рд▓ рдХрд╛ рд╣реИред

рдХреНрдпреЛрдВ? рдпрд╣ рдПрдВрдбрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рд╣реИ: рдЯрд╛рдбрд╛: (https://github.com/microsoft/TypeScript/pull/30769)ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдореБрдЭреЗ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдЕрдиреБрдХреНрд░рдорд┐рдд рд╕реНрдерд┐рддрд┐рдпреЛрдВ (рдПрдХ рд╕реНрд╡рд┐рдЪ рдХреА рддрд░рд╣) рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕рдиреЗ ts-toolbelt рдХреЗ рд▓рд┐рдП x6 рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ред рдмрд╣реБрдд-рдмрд╣реБрдд, рдЙрдирдХрд╛ рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред

рддреЛ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ, рд╣рдо ts- toolbelt рдХреЗ рд╕рд╛рде

import {O, I, T} from 'ts-toolbelt'

// It works with the same principles `Minus` uses
type Assign<O extends object, Os extends object[], I extends I.Iteration = I.IterationOf<'0'>> = {
    0: Assign<O.Merge<Os[I.Pos<I>], O>, Os, I.Next<I>>
    1: O
}[
    I.Pos<I> extends T.Length<Os>  
    ? 1
    : 0
]

type test0 = Assign<{i: number}, [
    {a: '1', b: '0'},
    {a: '2'},
    {a: '3', c: '4'},
]>

рд▓рд┐рдм Iteration рд╕рд╛рде рд░рд┐рдХрд░реНрд╕рди рдХреЛ рднреА рд╕реБрд░рдХреНрд╖рд┐рдд рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рдХрд┐рд╕реА рднреА рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрджрд┐ I 40 рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдпрд╣ рдУрд╡рд░рдлреНрд▓реЛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ Pos<I> рдмрд░рд╛рдмрд░ рд╣реЛрддрд╛ рд╣реИ number ред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд░рд┐рдХрд░реНрд╕рди рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд░реЛрдХрдирд╛ред

рдПрдХ рд╕рдорд╛рди рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рдЬреЛ рдореИрдВрдиреЗ рд▓рд┐рдЦрд╛ рдерд╛ ( Curry ) рд░рд╛рдорджрд╛ рдХреЗ рд╕рд╛рде рднреЗрдЬ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдЪреНрдЫрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред

рд╡реИрд╕реЗ, рдореИрдВрдиреЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдкреГрд╖реНрда рдкрд░ рдЖрдкрдХреА рд╕рднреА рдЕрдЪреНрдЫреА рд╕рд▓рд╛рд╣ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ (@jcalz) рдзрдиреНрдпрд╡рд╛рдж рджрд┐рдпрд╛ред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ #5453 рдЗрд╕ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рд╣реИ... рдХреНрдпрд╛ рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ #26980 рдореЗрдВ рдмрд╛рдд рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рдпрд╛ рдХреЛрдИ рдФрд░ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рд╕реНрдерд╛рди рд╣реИ? рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рдЗрд╕ рдЬреЛ рд╕рдВрднрд╡рддрдГ рдЯрд╛рдЗрдкрдкреНрд░рддрд┐ рдХреЗ рдмрд╛рдж рдХреЗ рд░рд┐рд▓реАрдЬ рдкрд░ рдлрдЯрдирд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рдХрд╛рд░реА рдФрд░ рд╕рдорд░реНрдерд┐рдд рддрд░реАрдХрд╛ рд╣реИ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдЙрдирдХреЗ рдмреЗрд╕рд▓рд╛рдЗрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ рддрд╛рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдЯреВрдЯ рдЬрд╛рдП рддреЛ рд╡реЗ рдЗрд╕реЗ рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдЕрдЧрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдореИрдВ рдХрд┐рд╕реА рднреА рдЙрддреНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ @ahejlsberg рдЬреИрд╕реЗ рдХрд┐рд╕реА рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╢рдмреНрдж рдХреЗ рдмрд┐рдирд╛ рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ рд╕рд╛рд╡рдзрд╛рди рд░рд╣реВрдВрдЧрд╛ред

рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдЙрдирдХреЗ рдмреЗрд╕рд▓рд╛рдЗрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ рддрд╛рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдЯреВрдЯ рдЬрд╛рдП рддреЛ рд╡реЗ рдЗрд╕реЗ рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рдмрд╣реБрдд рдХрд░реАрдм рд╣реИ

@weswigham рдореБрдЭреЗ рдШрдиреЗ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреНрд░рдХрд╛рд░ рд░рд┐рдХрд░реНрд╕рд┐рд╡ рдХреИрд╕реЗ рд╣реИ? рдореИрдВ рдЬрд┐рд╕ рдЪреАрдЬ рдХреЛ рд▓реЗрдХрд░ рдЪрд┐рдВрддрд┐рдд рд╣реВрдВ рд╡рд╣ рд╣реИ рдлреЙрд░реНрдо

type Foo<T> = { a: Foo<Bar<T>>, b: Baz }[Qux<T> extends Quux ? "a" : "b" ]

рдпрд╛ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦреЗ рдЧрдП рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗред рдЕрдЧрд░ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рд╣рд░реА рдмрддреНрддреА рджреА рдЧрдИ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдХреЛрдИ рдореБрдЭреЗ рдмрддрд╛рдПрдВ (рдФрд░ рдореБрдЭреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рд┐рдЦрд╛рдПрдВ!)

рдУрд╣, рдирд┐рд╖реНрдкрдХреНрд╖ - рдпрд╣ рдЙрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ рдЕрд▓рдЧ рд╣реИ, рд╣рд╛рдБред рдореИрдВ рд╕рд┐рд░реНрдл "рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреБрд░рдВрдд рдЕрдиреБрдХреНрд░рдорд┐рдд рд╡рд╕реНрддреБ" рдкреИрдЯрд░реНрди рдХрд╣рддрд╛ рд╣реВрдВ рдФрд░ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ _that_ рдерд╛ред

рдореЗрд░рд╛ рдПрдХ рд╕рд╡рд╛рд▓ рд╣реИред

рдпрд╣рд╛рдВ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдХрд┐рддрдирд╛ рд╣рд┐рд╕реНрд╕рд╛ рдЕрднреА рднреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ? рдпрд╣ рдореБрджреНрджрд╛ 4 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдЦреЛрд▓рд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рддрдм рд╕реЗ рд╕рд╛рдорд╛рди рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред

рдореЗрд░реА рдЯрд┐рдкреНрдкрдгреА рдпрд╣рд╛рдБ рд╕реЗ,
https://github.com/microsoft/TypeScript/issues/33778#issuecomment -537877613

рдореИрдВрдиреЗ рдХрд╣рд╛,

рдЯреАрдПрд▓; рдбреАрдЖрд░, рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░, рдмрд╛рдХреА рддрд░реНрдХ, рдореИрдк рдХрд┐рдП рдЧрдП рд╕рд░рдгреА рдкреНрд░рдХрд╛рд░, рдЧреИрд░-рдмрд╛рдХреА рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЯрдкрд▓-рдЕрдиреБрдорд╛рди, рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рдЙрдкрдирд╛рдо = рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдкреНрд░рдХрд╛рд░ рддрд░реНрдХ рд╕рдорд░реНрдерди рдХреА рдХреЛрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ

рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЗ рдкрд╛рд╕ рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореМрдЬреВрджрд╛ рдЯреВрд▓ рджреНрд╡рд╛рд░рд╛ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

рдЬрдм рддрдХ рд╣рдореЗрдВ Concat<T extends any[], U extends any[]> рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдзрдиреНрдп рд╕рдВрд╕реНрдХрд░рдг рдирд╣реАрдВ рдорд┐рд▓ рдЬрд╛рддрд╛, рддрдм рддрдХ рдпрд╣ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдЧрд╛рдореА рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рд╕рдВрджрд░реНрдн рд╕реБрд╡рд┐рдзрд╛ рд╣рдореЗрдВ рдпрд╣ рджреЗрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ (рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ) рдЕрдиреНрдпрдерд╛ рдмрддрд╛рдП рдЬрд╛рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред

рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА Concat<> рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВ рд╣реИ?

рдпрд╛ рдпрд╣рд╛рдБ рдореБрдЦреНрдп рд╡рд╛рдХреНрдпрд╛рдВрд╢ "рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддреМрд░ рдкрд░ рдзрдиреНрдп" рд╣реИ?

рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рджрд╛рд╡рд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рдм рдХреБрдЫ (рдпрд╛ рд▓рдЧрднрдЧ рд╕рдм рдХреБрдЫ?) рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдк рдЗрд╕ рд╕рдордп рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рднрд▓реЗ рд╣реА рд╡рд╣ "рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддреМрд░ рдкрд░ рдзрдиреНрдп" рди рд╣реЛред

рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ "рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддреМрд░ рдкрд░ рдзрдиреНрдп" рдХреЛ рд╣рдореЗрд╢рд╛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП ... рдЕрдЪреНрдЫреА рдмрд╛рддред рдореИрдВ рднреА рдЙрди рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдирд╛рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ (ab) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ

рдореИрдВ рдЖрдо рддреМрд░ рдкрд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ, рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рд╣рд░ рдмрд╛рд░ рдЬрдм рдореИрдВ рдРрд╕рд╛ рдХреБрдЫ рдХрд░реВрдВ рддреЛ рдореБрдЭреЗ рдЕрдкрдиреЗ (рдЕрдХреНрд╕рд░ рдЬреВрдирд┐рдпрд░) рдЯреАрдо рдХреЗ рд╕рд╛рдерд┐рдпреЛрдВ рдХреЛ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рднреНрд░рдорд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдпрдерд╛рд╕реНрдерд┐рддрд┐ рдХреЗ рджреБрд░реБрдкрдпреЛрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рднреНрд░рдо рдореЗрд░реА org.

рдЗрд╕ рдкрд░ рдмрдбрд╝рд╛ !

рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ SO рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

@AnyhowStep

рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рджрд╛рд╡рд╛ рд╣реИ рдХрд┐ рдЖрдк рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рдм рдХреБрдЫ (рдпрд╛ рд▓рдЧрднрдЧ рд╕рдм рдХреБрдЫ?) рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдк рдЗрд╕ рд╕рдордп рдЪрд╛рд╣рддреЗ рд╣реИрдВ

рдореБрдЭреЗ рдХреЛрдИ рд╕рдмреВрдд рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрдИ рд╕рд┐рдВрдЧрд▓ рдкреИрд░рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдкреНрд░реЗрдб рдкрд░рдо рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЖрдЬ рдЯреАрдПрд╕ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

@ рдореИрдереНрдпреВ-рдбреАрди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдХреБрдЫ рд╣рдж рддрдХ рд╣рд╛рд╕рд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ TS рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╡реИрдирд┐рд▓рд╛ JS рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдПрдХ рдкрд╣реЗрд▓реА рд╣реИ:

const f = <T extends any[]>(...args: T): T => args;
const g = <T extends any[]>(...a: T): WhatExactly<T> => {
    return f(3, ...a, 4, ...a, 5);
}
g(1, 2);

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ [number, ...T, number, ...T, number] рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдЕрдЧрд░ рд╣рдореЗрдВ рдХреБрдЫ рдЕрдЬреАрдм рдХреЛрдб рдХреА 20 рд▓рд╛рдЗрдиреЗрдВ рд▓рд┐рдЦрдиреА рд╣реИрдВ рдЬреЛ рдмрдЧ рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИрдВ рддреЛ рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдореЗрдВ рдЙрдЪрд┐рдд рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ, рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

@ polkovnikov-ph рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ: [number,┬а...any[]] , рдЬреЛ рдЕрдиреБрдкрдпреЛрдЧреА рд╣реИред

рд╕рд╛рде рд╣реА рдореИрдВ рдпрд╣ рднреА рдиреЛрдЯрд┐рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рд╣рдореЗрдВ рдЧреНрд░реАрдирд╕реНрдкрди рдХреЗ рджрд╕рд╡реЗрдВ рдирд┐рдпрдо рдХрд╛ 15 рд╡рд░реНрд╖реЛрдВ рддрдХ рд╕рдореНрдорд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ C++ рдиреЗ рдХрд┐рдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ C++ рдкрд╣рд▓реЗ рд╣реА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рднреА Head<> s рдФрд░ Cons<> рд╕реЗ рдЧреБрдЬрд░ рдЪреБрдХрд╛ рд╣реИ, рдФрд░ рдХреБрдЫ рдмрд╣реБрдд рд╣реА рдЖрд╕рд╛рди рдФрд░ рд╕реНрд╡рдЪреНрдЫ рд╡рд┐рд╡рд┐рдз рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред рд╣рдо рдбреЗрд╡рд▓рдкрд░ рд╕рдордп (рд╕реИрдХрдбрд╝реЛрдВ рд╡рд░реНрд╖) рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рдХреЗрд╡рд▓ рд╕рд░реНрд╡реЛрддреНрддрдо рднрд╛рдЧреЛрдВ рдХреЛ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ C++ рдореЗрдВ рднрд┐рдиреНрди extends any[] рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬрд╣рд╛рдВ рдкреНрд░рдХрд╛рд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ, рд╡рд╣рд╛рдВ рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдпрд╣ рд╕реА ++ рдХреЛ рдЗрд▓рд┐рдкреНрд╕рд┐рд╕ рдСрдкрд░реЗрдЯрд░ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХреБрдЫ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЕрдВрджрд░ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдЪрд░ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдХреЗ рдЯреБрдкрд▓реНрд╕ рдкрд░ рдореИрдк/рдЬрд╝рд┐рдк рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдореИрдк рдХрд┐рдП рдЧрдП рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рдЯрдкрд▓ рд╡рд┐рдХрд▓реНрдк рд╣реИред

type Somethify<...T> = [...Smth<T>]
type Test1 = Somethify<[1, 2]> // [Smth<1>, Smth<2>]

type Zip<...T, ...U> = [...[T, U]]
type Test2 = Zip<[1, 2], [3, 4]> // [[1, 3], [2, 4]]

type Flatten<...T extends any[]> = [......T]
type Test3 = Flatten<[[1, 2], [3, 4]]> // [1, 2, 3, 4]

рдХреГрдкрдпрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВ рдХрд┐ extends any[] рдмрдЬрд╛рдп рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдЗрд▓рд┐рдкреНрд╕рд┐рд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рди рдХреЗрд╡рд▓ рд╕реМрдВрджрд░реНрдп рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЗрд╕рд▓рд┐рдП рдХрд┐

type A<T> = any[]
type B<T extends any[]> = [...A<T>]
type C = B<[1, 2]>

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╡реИрдз TS рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИред C рдЕрдВрдд рдореЗрдВ any[] рдмрдЬрд╛рдп [any[], any[]] рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдореИрдк рдХрд┐рдП рдЧрдП рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред

@DanielRosenwasser рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕ рддрд░рд╣ рдкрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рддрд╛рдХрд┐ рдпрд╣ рдореМрдХрд╛ рдмрдврд╝реЗ рдХрд┐ рдЗрд╕реЗ рдХреБрдЫ рдкреНрдпрд╛рд░ рдорд┐рд▓реЗред рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд╕реБрдкрд░ рд╕рд╣рд╛рдпрдХ рд╣реЛрдВрдЧреЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдПрдХ рдмрдбрд╝рд╛ рдХрд╛рдо рд╣реИ!

рдПрдХ рддрд░рдл рдХреЗ рд░реВрдк рдореЗрдВ, рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк-рд▓реЗрд╡рд▓ рд╕реНрдкреНрд░реЗрдб рдСрдкрд░реЗрд╢рдВрд╕ рд╣реЛрдиреЗ рд╕реЗ рдореЗрд░реА рдЯреАрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝реА рдорджрдж рд╣реЛрдЧреА, рднрд▓реЗ рд╣реА рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рдХреА рдХрдореА рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рдбреЛрдореЗрди "рдХреБрдЫ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рд╕рд░рдгрд┐рдпрд╛рдБ" рдмрд╣реБрдд рдЖрдо рд╣реИрдВред рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЪреАрдЬреЛрдВ рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓ рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдпрд╣ рдСрдкрд░реЗрд╢рди рдХрд╛рдо рдХрд░реЗрдЧрд╛:

type SharedValues = [S1, S2, S3];
type TupleOfSpecificKind = [V1, ...SharedValues, V2];

@sethfowler рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬреЛ рдЖрдк рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рд╣реЛрддрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛ рдЖрдкрдХреЛ https://github.com/microsoft/TypeScript/issues/26113 . рдореЗрдВ рд░реБрдЪрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИ

@DanielRosenwasser рдЬрд╝рд░реВрд░, рдореИрдВ рдЪреАрдЬреЛрдВ рдХреЛ рдереЛрдбрд╝рд╛ рдФрд░ рдареЛрд╕ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВред рдореИрдВ рдЗрд╕рдореЗрдВ рд╕реЗ рдмрд╛рд░реАрдХ-рдмрд╛рд░реАрдХ рдЪреАрдЬреЗрдВ рд░рдЦреВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЙрдЪреНрдЪ рд╕реНрддрд░ рдкрд░ рдЖрдк рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╕рдВрдЪрд╛рд▓рди рдФрд░ рдЕрдиреНрдп рд╕рдорд╛рди рдШрдЯрдирд╛рдУрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЬреЛ рдПрдХ рджреВрд░рд╕реНрде рд╕рд░реНрд╡рд░ рдкрд░ рднреЗрдЬреА рдЬрд╛рддреА рд╣реИред рджрдХреНрд╖рддрд╛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╣рдореЗрдВ рдЙрди рдкрд░рд┐рдЪрд╛рд▓рдиреЛрдВ рдХреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рдПрдХ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╕реАрдзреЗ рдЙрдирдХреЗ рдХреНрд░рдордмрджреНрдз рд░реВрдк рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдпреЛрдЧреНрдп рд╣реИред рдЗрди рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ:

type OpLineSegment = [
  StrokeColor,
  FillColor,
  number,  // thickness
  number, number, number,  // X0, Y0, Z0
  number, number, number  // X1, Y1, Z1
];
type OpCircle = [
  StrokeColor,
  FillColor,
  number, number, number,  // X, Y, Z of center
  number // radius
];
type OpPolygon = (StrokeColor | FillColor | number)[];  // [StrokeColor, FillColor, repeated X, Y, Z]]
type OpFan = (StrokeColor | FillColor | number)[];  // StrokeColor, FillColor, repeated X, Y, Z up to 10x

рд╣рдо рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдЗрд╕ рддрд░рд╣ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

type Colors = [StrokeColor, FillColor];
type Vertex3D = [number, number, number];

type OpLineSegment = [...Colors, number /* thickness */, ...Vertex3D, ...Vertex3D];
type OpCircle = [...Colors, ...Vertex3D, number /* radius */];
type OpPolygon = [...Colors, ...Repeated<...Vertex3D>];
type OpFan = [...Colors, ...RepeatedUpToTimes<10, ...Vertex3D>];

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрди рдЖрджреЗрд╢реЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЗрд╡рд▓ рдЯрд╛рдЗрдк-рд╕реНрддрд░реАрдп рдкреНрд░рд╕рд╛рд░ рд╣реЛрдиреЗ рд╕реЗ рдирд╛рдЯрдХреАрдп рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рд░рдЦрд░рдЦрд╛рд╡ рдпреЛрдЧреНрдп рдХреЛрдб рд╣реЛрдЧрд╛ред рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рд╣рдо рдЯрд╛рдЗрдк-рд╕реНрддрд░реАрдп рдлрд╝рдВрдХреНрд╢рдВрд╕ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ Repeated<> рдФрд░ RepeatedUpToTimes<> (рдЬреЛ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЯреБрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдкреБрдирд░рд╛рд╡рд░реНрддреА-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдпреВрдирд┐рдпрдиреЛрдВ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░реЗрдВрдЧреЗ) рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рднреА рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред

рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЯрд╛рдЗрдк-рд╕реЗрдл рдХреЙрдиреНрд╕рдЯреЗрдиреЗрд╢рди (рдЬреИрд╕рд╛ рдХрд┐ рдУрдкреА рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИ) рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реЛрдирд╛ рднреА рдмреЗрд╣рдж рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдЙрдкрд░реЛрдХреНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдПрдХрд▓ рдЯрдкрд▓ рд╢рд╛рдмреНрджрд┐рдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рд╕рдВрдкреВрд░реНрдг рдЯрдкрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдЗрд╕реЗ рднрд╛рдЧреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрднреА рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдСрдкрд░реЗрд╢рди рдЖрдЬ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдХрд┐рдпрд╛ред

const colors: Colors = getColors();
const center: Vertex3D = getCenter();

// Doesn't work! Produces a homogenous array.
const circle1: OpCircle = [...colors, ...center, radius];

// Doesn't work; can't write this function today.
const circle2: OpCircle = concat(colors, center, radius);

// We need to do this today; it's quite painful with more complex tuple types.
const circle3: OpCircle = [colors[0], colors[1], center[0], center[1], center[2], radius];

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпреЗ рдЙрджрд╛рд╣рд░рдг рдорджрджрдЧрд╛рд░ рд╣реЛрдВрдЧреЗ!

рдЖрдк Concat<> рдкреНрд░рдХрд╛рд░ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ Concat3<> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Concat<> ред

рдлрд┐рд░,

type OpCircle = Concat3<Colors, Vertex3D, [number] /* radius */>;

рдКрдкрд░ рд╕реЗ, рдЖрдк 2,3,4,5,6, рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд▓реЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рдХреЙрдиреНрд╕реИрдЯ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рддрд░реНрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред

Concat<> impl рд▓рд┐рдЦрдирд╛ рднреА рд╕рдВрднрд╡ рд╣реИ рдЬреЛ рдЯреБрдкрд▓реНрд╕ рдХрд╛ рдПрдХ рдЯрдкрд▓ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдПрдХ var-arg Concat<> рдкреНрд░рдХрд╛рд░ред


рдпрд╣ рдХреЛрдИ рдРрд╕реА рдЪреАрдЬ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЖрдЬ рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреАред рдпрд╣ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░, рдФрд░ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред

рд╣рд░ рдмрд╛рд░ рдЬрдм рдореИрдВ рдмрдирд╛рдо рдХреЛрдб рдореЗрдВ рдЙрди рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдЯреАрдПрд╕ рд╕реАрдкреАрдпреВ рдХреЛ рдорд╛рд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рдпрд╛ рдпрд╣ рдмрд╕ рд▓рдЯрдХрддрд╛ рд╣реИ! рдпрд╣реА рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрдЪреНрдЫреЗ рдХрд╛рд░рдг рдХреЗ рдЯреАрдПрд╕ рдмрд╣реБрдд рднрд╛рд░реА рд╣реЛ рд░рд╣рд╛ рд╣реИред

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдк рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ рдЗрд╕реЗ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ?

рдореИрдВ рдкреБрд░рд╛рдиреА рдмрд╛рддрдЪреАрдд рдореЗрдВ рд╕реНрдкреИрдо рдпрд╛ рдбреНрд░реИрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛, рдЬреЛ рдЗрд╕ рдзрд╛рдЧреЗ рдореЗрдВ рдЕрдзрд┐рдХ рдореВрд▓реНрдп рдирд╣реАрдВ рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рдпрд╛рдж рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдорд╣рдВрдЧреА рд╣реИ (рдореИрдВрдиреЗ рдЗрд╕реЗ рдпрд╣рд╛рдВ рдЗрд╕ рдзрд╛рдЧреЗ рдореЗрдВ рдкрд╛рдпрд╛)

рдЙрд╕ рдиреЗ рдХрд╣рд╛ (рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╛рдЧрд▓ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ,) рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЯреАрдПрд╕ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рднрд╛рд╖рд╛ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реЛ рддрд╛рдХрд┐ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рдорд┐рд▓ рд╕рдХреЗ рдХреНрдпреЛрдВрдХрд┐ рдЯреАрдПрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрддрдирд╛ рдмрдбрд╝рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдмреЗрд╣рддрд░ рдХреЗ рд▓рд┐рдП рдкреВрдЫрдирд╛ рдЙрдЪрд┐рдд рд╣реИред

рдЖрдк Concat<> рдкреНрд░рдХрд╛рд░ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ Concat3<> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Concat<> ред

рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЙрд╕ Concat<> рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЖрдк рд╡рд░реНрдгрди рдХрд░ рд░рд╣реЗ рд╣реИрдВ? Cons<> рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди Concat<> рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ (рдореЗрд░реЗ рд▓рд┐рдП) рдФрд░ рдореБрдЭреЗ рдпрд╣ рджреЗрдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдХрд▓реНрдкрдирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

Concat3<> , Concat4<> , рдЖрджрд┐ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ, рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд▓рдВрдмреА рдЕрд╡рдзрд┐ рдореЗрдВ рд╣рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рджрд░реНрдЬрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░ рд╣реЛрдВрдЧреЗред рдпрджрд┐ рдЖрдЬ рдЙрдирдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдВрднрд╡ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рдЙрдЪрд┐рдд рд╕реНрдЯреЙрдкрдЧреИрдк рдЙрдкрд╛рдп рд╣реЛрдЧрд╛ред

рджреЛ рдЯреБрдкрд▓реНрд╕ рдХреЗ рдирд┐рдпрдорд┐рдд рд╕рдВрдпреЛрдЬрди рдХреЗ рд▓рд┐рдП,
https://github.com/AnyhowStep/ts-trampoline-test (рдмрд╣реБрдд рдмрдбрд╝реЗ рдЯреБрдкрд▓реНрд╕ рдХреЛ рдХреЙрдирдХреИрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрдореНрдкреЛрд▓рд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЛрдЧреЛрдВ рдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА)

Concat3 рд╕рд┐рд░реНрдл Concat , рд╕реА>

VarArgConcat рд╣реЛрдЧрд╛,
VarArgConcat<TuplesT extends readonly (readonly unknown[])[], ResultT extends readonly unknown[] = []>

рдЬрдмрдХрд┐ рдЯрдкрд▓ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, VargArgConcat<PopFront<TuplesT>, Concat<ResultT, TuplesT[0]>>

рдпрджрд┐ TuplesT рдЦрд╛рд▓реА рд╣реИ, рддреЛ ResultT рд▓реМрдЯрд╛рдПрдВ

рдмреЗрд╢рдХ, рдирд┐рд╖реНрдкрдХреНрд╖ рд░рд┐рдХрд░реНрд╕рди рдПрдХ рд╕рднреНрдп рд▓рдВрдмрд╛рдИ рдХреЗ рдЯреБрдкрд▓реНрд╕ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХрддрдо рдЧрд╣рд░рд╛рдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЬрдиреНрдо рджреЗрдЧрд╛ред рддреЛ, рдпрд╛ рддреЛ рдЯреАрдПрд╕-рдЯреВрд▓рдмреЗрд▓реНрдЯ рдореЗрдВ рд░рд┐рдХрд░реНрд╕рди рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдпрд╛ рд╡рд╛рдВрдЫрд┐рдд рдЧрд╣рд░рд╛рдИ рддрдХ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдЯреНрд░реИрдореНрдкреЛрд▓рд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


рдореИрдВ рдЬрд┐рд╕ рд░реЗрдкреЛ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реВрдВ рд╡рд╣ Reverse<> рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Concat<> ред рдореИрдВрдиреЗ рдЬрд┐рд╕ рдЕрдиреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЙрд╕рдХреЗ рдХреЛрдб рдХреЛ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХрд┐рдпрд╛ред

рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдпрд╣ рдПрдХ рдЬрдмрд░рджрд╕реНрдд рдЙрдкрдпреЛрдЧреА рд╕реБрд╡рд┐рдзрд╛ рд╣реЛрдЧреАред

рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ T :

type T = {
  tags: ["a", "b", "c"];
};

рдФрд░ рд╣рдо T["tags"] рдЯрдкрд▓ рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЯреИрдЧ "d" рд╕рд╛рде рдПрдХ рдирдпрд╛ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╢реБрд░реВ рдореЗрдВ рдЗрд╕ рдЙрдкрдпреЛрдЧрд┐рддрд╛ ( WithTag<NewTag, ApplyTo> ) рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

type WithTag<
  Tag extends string,
  Target extends {tags: string[]}
> = Target & {
  tags: [Tag, ...Target["tags"]];
};

рдЗрд╕рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╡рд░реНрддрдорд╛рди рдореЗрдВ A rest element type must be an array type рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ string[] рд▓рд┐рдП Array<string> рдЕрджрд▓рд╛-рдмрджрд▓реА рдХрд░рдиреЗ рд╕реЗ рдлрд░реНрдХ рдкрдбрд╝рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред рди рд╣реА рдПрдХ рд╢рд░реНрдд + never рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:

type WithTag<
  Tag extends string,
  Target extends {tags: string[]}
> = Target & {
- tags: [Tag, ...Target["tags"]];
+ tags: Target["tags"] extends string[] ? [Tag, ...Target["tags"]] : never;
};

рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рд▓рд┐рдВрдХ: https://www.typescriptlang.org/play?#code/C4TwDgpgBA6glsAFgFQIYHMA8AoKU3pQQAewEAdgCYDOU1wATnOegDS76oPoTBGkUaUAN7AM1AFx1GzdAG0AugF9sAPigBeTt15QAZCI5j0kqHIKsoAOhtodwOQCJj1RwoUBubEq -ZQkKABJTUM8FyknVEdLRwAjaKhHAGM3Lx9sP3BoZBD4JAJMR0oEwNVfAHoAKkrcSqgAUWJIJLJKKAADZHaoYAB7KFjoXoAzHsRoYd6AGynegHdZHqyrWqhV4VWe8QjHKJj4mJSY4s9VlShK8qA

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЗ: :

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рд░рдгрдиреАрддрд┐ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдпреЗ рд╕рд┐рд░реНрдл рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВ:

function i(a: number, b?: string, ...c: boolean[]): number {
}
let curried = curry(i, 12);
curried('foo', [true, false]);
curried([true, false]);

рдпрд╣рд╛рдБ, рдХрд░реА: ...([string, boolean[]] | [boolean[]]) => number ред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЯреБрдкрд▓ рд░реЗрд╕реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рдерд╛, рдЬрд╣рд╛рдВ рдЯреБрдкрд▓ рдХрд╛ рдЕрдВрддрд┐рдо рддрддреНрд╡ рдПрдХ рд╕рд░рдгреА рд╣реИред
рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╕рд░рдгреА рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╕рд╛рд░реНрдердХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд▓рдЧрддрд╛ рд╣реИред

рдЗрд╕рдореЗрдВ рджреЛ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ:

  1. рдХреЛрдб рдЧрд▓рдд рд╣реИред curried() рдПрдХ рд╕рд░рдгреА рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рднрд░рдиреЗ c рдХреЗ рд╕рд╛рде рдЖрд░рд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ [true, false] рдХреЗ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ curried('foo', ...[true, false]) рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рд╕реБрдЭрд╛рд╡ рд╕реЗ рдЯрд╛рдЗрдкрдкреНрд░рддрд┐ рдореЗрдВ рдЕрд╕рдлрд▓ рд╣реЛ рдЬрд╛рдпреЗрдЧреАред рд╣рдо рдХрд┐рд╕реА рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХреЛ рдЧрд▓рдд рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ!
  2. рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ, рдЖрдкрдиреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рдФрд░ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЬреЛрдбрд╝ рджрд┐рдпрд╛, рдФрд░ рдЕрдкрдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдПрдХ рдмрдЧ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд┐рдпрд╛ред curried() рдХреЛ b рдмрд┐рдирд╛ рдирд╣реАрдВ рдмрд▓реНрдХрд┐ c рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ рдЧрд▓рдд рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛрдЧрд╛ред рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ curried() (...items: [string, boolean[]] | [boolean[]]) рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИ ред рдХреНрдпреЛрдВрдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯрд╛рдЗрдкрд┐рдВрдЧ-рд░рд╣рд┐рдд рд╣реИ, [true, false] рд╕реЗ c (рдпрд╣ рдорд╛рдирддреЗ рд╣реБрдП рдХрд┐ рд╣рдордиреЗ рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХрд░ рд▓реА рд╣реИ) рдХреЛ curried([true, false]) рдХрд░рдиреЗ рд╕реЗ b рд╕реЗ undefined рд╕реЗрдЯ рдирд╣реАрдВ рд╣реЛрдЧрд╛ c рд╕реЗ [true, false] , рд▓реЗрдХрд┐рди b рд╕реЗ true рдФрд░ c рд╕реЗ [false] !

рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реБрдзрд╛рд░реЛрдВ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ:

  1. рджреВрд╕рд░реА (рдФрд░ рдЖрд╕рд╛рди) рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП, рд╕рдорд╛рдзрд╛рди рд╕рд░рд▓ рд╣реИ: рдЕрдВрддрд┐рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рддрд░реНрдХ (рдпрд╛рдиреА рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ [number, string, boolean[]] | [number, boolean[]] ) рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдпрди рдЯрдкрд▓ рдХрд╛ рдЕрдиреБрдорд╛рди рди рд▓рдЧрд╛рдПрдВ, рдЬрдм рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, [number, string, boolean[]] | [number] рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдПрдВ - рдпрд╛рдиреА, рдкреВрд░реНрдг рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдорд▓рд╛, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рд╡реИрдХрд▓реНрдкрд┐рдХ рдФрд░ рдмрд╛рдХреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЕрдВрддрд┐рдо рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреЗ рд▓рд┐рдП рдПрдХ, рдФрд░ рдЕрдВрддрд┐рдо рдФрд░ рд╢реЗрд╖ рдХреЗ рдмрд┐рдирд╛ рдПрдХред
  2. рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ: рдЖрдк рдкрд╣рд▓реЗ рд╣реА рдХрд╣ рдЪреБрдХреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╛рд░реНрдердХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдпрд╣ _is_ рд╕рд╛рд░реНрдердХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ (рдЬреАрдд! ) рдХреЗ рдХрд╛рд░рдг _necessary_ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо tuple-with-last-rest-array (рдореИрдВ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрддрд╛ рд╣реВрдВ [t1, t2, t3, ...arr] ) рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдПрдХ рдЖрдВрддрд░рд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рд░рд╣ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рд╛рд╣рд╛, рдЖрдкрдХреЛ рдЕрднреА рднреА рдПрдХ рдЖрдИрдбреАрдИ рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕реЗ рдирд┐рдкрдЯрдирд╛ рд╣реЛрдЧрд╛)ред

рд▓реЗрдХрд┐рди рддрдорд╛рдо рд╢рд┐рдХрд╛рдпрддреЛрдВ рдФрд░ рдЙрдХрд╕рд╛рд╡реЗ рдХреЗ рдмрд╛рдж рдмрдврд╝рд┐рдпрд╛ рдкреНрд░рд╕реНрддрд╛рд╡! рдзрдиреНрдпрд╡рд╛рдж (рдмрд╕ рдЖрдкрдХреЛ рд╢рд╛рдВрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ GitHub рдореЗрдВ рдЕрдм рддрдХ рдХрд╛ рдкрд╣рд▓рд╛ рдореБрджреНрджрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореИрдВрдиреЗ рддреАрди рдЗрдореЛрдЬреА - ЁЯСН, рдФрд░ тЭдя╕П рдХреЗ рд╕рд╛рде рдЬрд╡рд╛рдм рджрд┐рдпрд╛)ред

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдгреАрдп рдЗрдВрдЬреЗрдХреНрдЯрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ any https://github.com/angular/angular/issues/37264 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдП, рдмреА, рд╕реА рдХреЛ рдПрдХрд▓ ...A рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдРрд╕реА рдЪреАрдЬ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдореИрдк рдХрд░реЗрдЧрд╛ рдЬрд╣рд╛рдВ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдиреЗрд░рд┐рдХ рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ ( Type ) рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реЛрдЧрд╛ред рд╢рд╛рдпрдж рдПрдХ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде? рдпрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ ...Type<A> рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП?

export declare interface TypedFactoryProvider<T, A, B, C> {
    provide: Type<T | T[]> | InjectionToken<T | T[]>;
    multi?: boolean;
    useFactory: (a: A, b: B, c: C) => T;
    deps: [Type<A>, Type<B>, Type<C>];
}

(рд╕рдВрджрд░реНрдн: Provider рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрд╕ рдХреНрд░рдо рдореЗрдВ рдЙрд╕ рдлрд╝реИрдХреНрдЯрд░реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ deps рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░реЗрдЧрд╛ред рдПрдХ рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдЧреА рдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХрд┐рд╕ рдХреНрд░рдо рдореЗрдВред)

рдЬрдм рдпрд╣ рд╣реЛ рдЬрд╛рдП рддреЛ рдХреГрдкрдпрд╛ String.prototype.replace рдХреЗ рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦреЗрдВ, рддрд╛рдХрд┐ рдЕрдВрдд рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЙрдЪрд┐рдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╣реЛ рд╕рдХреЗ!

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter

@ рдЧреНрд░рд┐рдлреЛрд░реНрдХ рдЖрдкрдХреЛ рдПрд╣рд╕рд╛рд╕ рд╣реИ рдХрд┐ рд░реЗрдЧреЗрдХреНрд╕ рдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдХрд┐ рдЙрд╕рдХреЗ рдкрд╛рд╕ рдХрд┐рддрдиреЗ рдХреИрдкреНрдЪрд░ рд╕рдореВрд╣ рд╣реИрдВ, рд╣реИ рдирд╛?

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдгреАрдп рдЗрдВрдЬреЗрдХреНрдЯрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ any рдХреЛрдгреАрдп/рдХреЛрдгреАрдп#37264 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдП, рдмреА, рд╕реА рдХреЛ рдПрдХрд▓ ...A рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдРрд╕реА рдЪреАрдЬ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдореИрдк рдХрд░реЗрдЧрд╛ рдЬрд╣рд╛рдВ рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЬреЗрдиреЗрд░рд┐рдХ рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ ( Type ) рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реЛрдЧрд╛ред рд╢рд╛рдпрдж рдПрдХ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде? рдпрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ ...Type<A> рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП?

export declare interface TypedFactoryProvider<T, A, B, C> {
  provide: Type<T | T[]> | InjectionToken<T | T[]>;
  multi?: boolean;
  useFactory: (a: A, b: B, c: C) => T;
  deps: [Type<A>, Type<B>, Type<C>];
}

(рд╕рдВрджрд░реНрдн: Provider рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрд╕ рдХреНрд░рдо рдореЗрдВ рдЙрд╕ рдлрд╝реИрдХреНрдЯрд░реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ deps рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░реЗрдЧрд╛ред рдПрдХ рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдЧреА рдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХрд┐рд╕ рдХреНрд░рдо рдореЗрдВред)

@AlexAegis

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

export declare interface TypedFactoryProvider<T, ...P> {
  provide: Type<T | T[]> | InjectionToken<T | T[]>;
  multi?: boolean;
  useFactory: (...providers: ...P) => T;
  deps: [...Type<P>];
}

рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЕрдм TS 4.0 рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд #39094 рджреНрд╡рд╛рд░рд╛ рдареАрдХ рдХрд░ рджреА рдЧрдИ рд╣реИред

рдпрджрд┐ рдпрд╣ 4.0 рдХреЗ рд╕рд╛рде рдЖ рд░рд╣рд╛ рд╣реИ, рддреЛ рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕реЗ 4.0 рдирд╛рдо рджреЗрдиреЗ рдХрд╛ рдПрдХ рдХрд╛рд░рдг рд╣реИ
рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдкреНрд░рдореБрдЦ рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ

рдпрд╣ рднреА рдЦреВрдм рд░рд╣реА! рд╢рд╛рдмреНрджрд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ "рдмрд╛рдПрдВ" рд╕рдорд╛рди рд╣реИ

@sandersn рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ RxJS рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдореЗрдВ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд╣рд╛рдВ pipe рд╡рд┐рдзрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИрдВ,

pipe(map<T, V>(...), map<V, U>(...), filter(...), ...) ред рдЖрдк рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╡реЗ рдЕрдм рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ? (рд╡рд┐рднрд┐рдиреНрди рднрд┐рдиреНрди рд▓рдВрдмрд╛рдИ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреА рджрд░реНрдЬрдиреЛрдВ рдкрдВрдХреНрддрд┐рдпрд╛рдБ)

@gioragutt рдиреЗ PR рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП @ahejlsberg рдиреЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛ рд▓реЗрдХрд┐рди рдореИрдВ рдЧрд▓рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реВрдВ рд╣рд╛рд▓рд╛рдВрдХрд┐

type Last<T extends readonly unknown[]> = T extends readonly [...infer _, infer U] ? U : undefined;

interface UnaryFunction<T, R> { (source: T): R; }

type PipeParams<T, R extends unknown[]> = R extends readonly [infer U] ? [UnaryFunction<T, U>, ...PipeParams<R>] : [];

function pipe<T, R extends unknown[]>(...fns: PipeParams<T, R>): UnaryFunction<T, Last<R>>;

рдЧреЛрд▓рд╛рдХрд╛рд░ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рдХреЗ рдХрд╛рд░рдг @tylorr рдХрд╛рдлреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рдордХрд╛рдЬ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ред

type Last<T extends readonly unknown[]> = T extends readonly [...infer _, infer U] ? U : undefined;

interface UnaryFunction<T, R> { (source: T): R; }

type PipeParams<T, R extends unknown[]> = {
    0: [],
    1: R extends readonly [infer U, ...infer V]
    ? [UnaryFunction<T, U>, ...PipeParams<U, V>]
    : never
}[R extends readonly [unknown] ? 1 : 0];

declare function pipe<T, R extends unknown[]>(...fns: PipeParams<T, R>): UnaryFunction<T, Last<R>>;

@isiahmeadows рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред рдореИрдВ
рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рдЙрджрд╛рд╣рд░рдг ред

рдореБрдЭреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдХрд░реАрдм рдХреБрдЫ рдорд┐рд▓рд╛ рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдХрдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рдЙрджрд╛рд╣рд░рдг

рдореБрдЭреЗ рдмрджрд▓рдирд╛ рдкрдбрд╝рд╛
R extends readonly [unknown] ? 1 : 0
рдкреНрд░рддрд┐
R extends readonly [infer _, ...infer __] ? 1 : 0

рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпреЛрдВ

@tylorr @treybrisbane рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: https://github.com/microsoft/TypeScript/pull/39094#issuecomment -645730082

рд╕рд╛рде рд╣реА, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдЙрд╕ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреА рдЕрддреНрдпрдзрд┐рдХ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдЬреЛ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рд╣реИред

рд╡реИрд░рд┐рдПрдбрд┐рдХ рдЯрдкрд▓ рдкреНрд░рдХрд╛рд░ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдврд╝рд┐рдпрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рд╣реИрдВ, рдкреНрд░рдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, curry рдЬреИрд╕реЗ рдирд┐рд░реНрдорд╛рдг рднреА рд▓рд╛рднрд╛рдиреНрд╡рд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдмрд╕ рд╕реНрдЯреЗрдЬрд┐рдВрдЧ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛):

// curry with max. three nestable curried function calls (extendable)
declare function curry<T extends unknown[], R>(fn: (...ts: T) => R):
  <U extends unknown[]>(...args: SubTuple<U, T>) => ((...ts: T) => R) extends ((...args: [...U, ...infer V]) => R) ?
    V["length"] extends 0 ? R :
    <W extends unknown[]>(...args: SubTuple<W, V>) => ((...ts: V) => R) extends ((...args: [...W, ...infer X]) => R) ?
      X["length"] extends 0 ? R :
      <Y extends unknown[]>(...args: SubTuple<Y, X>) => ((...ts: X) => R) extends ((...args: [...Y, ...infer Z]) => R) ?
        Z["length"] extends 0 ? R : never
        : never
      : never
    : never

type SubTuple<T extends unknown[], U extends unknown[]> = {
  [K in keyof T]: Extract<keyof U, K> extends never ?
  never :
  T[K] extends U[Extract<keyof U, K>] ?
  T[K]
  : never
}

type T1 = SubTuple<[string], [string, number]> // [string]
type T2 = SubTuple<[string, number], [string]> // [string, never]

const fn = (a1: number, a2: string, a3: boolean) => 42

const curried31 = curry(fn)(3)("dlsajf")(true) // number
const curried32 = curry(fn)(3, "dlsajf")(true) // number
const curried33 = curry(fn)(3, "dlsajf", true) // number
const curried34 = curry(fn)(3, "dlsajf", "foo!11") // error

рдЬреЗрдиреЗрд░рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдХрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдкреАрдЖрд░ рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИред

рдкреАрдЖрд░ рдХреЗ рд╕рд╛рде рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

function foo<T extends any[]>(a: [...T]) {
  console.log(a)
}

foo<[number, string]>([12, '13']);

рд▓реЗрдХрд┐рди рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ, рдпрд╣ рдореБрджреНрджрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ:

function bar<...T>(...b: ...T) {
  console.log(b)
}

bar<number, string>(12, '13');

рд╡рд╣рд╛рдБ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдг рдХреЛрд╖реНрдардХ рд╣реИрдВ, рдереЛрдбрд╝рд╛ рдмреЗрдорд╛рдиреА рд▓рдЧрддрд╛ рд╣реИред

@AlexAegis рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореБрдЭреЗ "рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░" рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореВрд▓реНрдп рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

declare function foo<T extends any[]>(...a: T): void;

foo(12, '13');  // Just have inference figure it out
foo<[number, string]>(12, '13');  // Expclitly, but no need to

рдРрд╕рд╛ рдордд рд╕реЛрдЪреЛ рдХрд┐ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдкреВрд░реА рдирдИ рдЕрд╡рдзрд╛рд░рдгрд╛ (рдпрд╛рдиреА рдмрд╛рдХреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░) рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рджреБрд░реНрд▓рдн рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реНрдХреНрд╡рд╛рдпрд░ рдмреНрд░реИрдХреЗрдЯ рд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЕрдиреБрдорд╛рди рдЗрд╕реЗ рд╕рдордЭ рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИред

@ahejlsberg рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдБред рдореИрдВ рдкреВрдЫ рд░рд╣рд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдХреБрдЫ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдиреЗ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдордХрд╛рдЬ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рд╕реАрдорд┐рдд рд╣реИред

bar<T1>(t1: T1);
bar<T1, T2>(t1: T1, t2:T2);
bar<T1, T2, T3>(t1: T1, t2:T2, t3: T3, ...t: unknown) { ... }

рддреЛ рдЕрдм рд╡реЗ рдпрд╛ рддреЛ рдЙрд╕реА рдкрд░ рдЯрд┐рдХреЗ рд░рд╣рддреЗ рд╣реИрдВ, рдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдмреНрд░реИрдХреЗрдЯ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдмреНрд░реЗрдХрд┐рдВрдЧ рдмрджрд▓рд╛рд╡ рд╣реИ, рди рдХрд┐ рд╕рд╣рдЬ рдЬреНрдЮрд╛рди рдпреБрдХреНрддред

рдореИрдВрдиреЗ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣рд╛рдБ рдпрд╣ рд╕реАрдзрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЙрд╕ рдЯрдкрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рдПрдХ рд╡рд░реНрдЧрд╛рдХрд╛рд░ рдХреЛрд╖реНрдардХ рдпрд╣рд╛рдБ, рдПрдХ рд╡рд╣рд╛рдБ

foo<[number, string]>([12, '13']);

рдпрд╣рд╛рдВ рдпрд╣ рдЗрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЯрдкрд▓ рдЙрд╕ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдмрд╛рд╣рд░ рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ

foo<[number, string]>(12, '13'); 

рд▓реЗрдХрд┐рди рд╣рд╛рдБ рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдХрд╣рд╛ рдерд╛ рдХрд┐ рдЕрдЧрд░ рд╣рдо рдЕрдиреБрдорд╛рди рдХреЛ рд╕рдордЭ рд▓реЗрддреЗ рд╣реИрдВ рддреЛ рдЗрди рддреБрдЪреНрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдХрд┐рд╕реА рднреА рд╕рдВрд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдпрд╣ рдЙрдирдХреЗ рдКрдкрд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЕрднреА рднреА рдПрдХ рдмреНрд░реЗрдХрд┐рдВрдЧ рдмрджрд▓рд╛рд╡ рдХреЗ рд░реВрдк рдореЗрдВ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд▓рд┐рдм рдХреА рдЪрд┐рдВрддрд╛ рд╣реИ рди рдХрд┐ рдЗрд╕ рдмрджрд▓рд╛рд╡ рдХреАред

рдЙрд╕ рдиреЗ рдХрд╣рд╛ рдХрд┐ рдореБрдЭреЗ рдпрд╣ рдЕрдЬреАрдм рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдмрд╛рд╣рд░ рд╕реЗ рдПрдХ-рдПрдХ рдХрд░рдХреЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдЬреЛ рдХрд┐ ... рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднреЗрджрд┐рдд рдЕрдВрджрд░ рдкрд░ рдПрдХ рдПрдХрд▓ рд╕рд░рдгреА рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рдПрдХ-рдПрдХ рдХрд░рдХреЗ рдмрд╛рд╣рд░ рдХреА рддрд░рдл, рдЕрдВрджрд░ рдХреА рддрд░рдл рд╕рд┐рдВрдЧрд▓ рдРрд░реЗ, ... рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднреЗрджрд┐рддред

рдорд╛рдореВрд▓реА рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡рд┐рд╕рдВрдЧрддрд┐рдпрд╛рдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд▓рд╛рдЧрдд рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИрдВ
рдкреНрд░рдХрд╛рд░ред рдЬрдм TS рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рдерд╛, рддрдм рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рд╕рд╣реА рдбрд┐рдЬрд╝рд╛рдЗрди рдирд┐рд░реНрдгрдп рд╣реЛрдЧрд╛
рдмрд╛рдХреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдм рдпрд╣ рдФрд░ рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ
рднрд╛рд╖рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рднреНрд░рдоред рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА
рдЗрд╕ рдореБрджреНрджреЗ, рдФрд░ рдПрдВрдбрд░реНрд╕ рдиреЗ рдЕрдкрдирд╛ рдХрд╛рдо рдЕрд╕рд╛рдзрд╛рд░рдг рд░реВрдк рд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЯрд╛рд▓рддреЗ рд╣реБрдП рдХрд┐рдпрд╛
рдХреЗ рд▓рд┐рдП рдЪрд┐рдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдЬрдЯрд┐рд▓рддрд╛ [...T] рдХреЗ рдмрдЬрд╛рдп T ред рд╕рд▓рд╛рдо!

(рдХреНрдпрд╛ рдЕрдм рд╣рдо рдПрдХ рдмрдЧ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ
рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рдЪрд░ рд╕рдмрд╕реЗ рджрд╛рд╣рд┐рдиреЗ рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдкреНрд░рдХрд╛рд░ рджреЗрддрд╛ рд╣реИ
рддрд░реНрдХ, рдпрд╛ рд╕рд░рдгрд┐рдпреЛрдВ рдХрд╛ рд╕рдВрдШ рдХреГрдкрдпрд╛ рд╕рдВрдШ рдХреА рд╕рд░рдгреА рдирд╣реАрдВ рд╣реИ? рд╣рдо рдЕрднреА рднреА
рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреНрд░рдореБрдЦ рд╢реЛрд╕реНрдЯреЙрдкрд░ рд╣реИрдВред)

рд╢реБрдХреНрд░, рдЬреВрди резреп, реирежреиреж, резреж:рекрез рдЧреНрдпреЛрд░реА рд╕реИрдВрдбреЛрд░ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдкрд░ рд▓рд┐рдЦрд╛ рд╣реИ:

@ahejlsberg https://github.com/ahejlsberg рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБред рдореИрдВ рдкреВрдЫ рд░рд╣рд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐
рдХреБрдЫ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдиреЗ рдЗрд╕реЗ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ
рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рд╕реАрдорд┐рдд рд╣реИред

рдЫрдбрд╝(t1: T1);рдмрд╛рд░(t1: T1, t2:T2); рдмрд╛рд░(t1: T1, t2:T2, t3: T3, ...t: рдЕрдЬреНрдЮрд╛рдд) {...}

рддреЛ рдЕрдм рд╡реЗ рдпрд╛ рддреЛ рдЙрд╕реА рдХреЗ рд╕рд╛рде рдЪрд┐рдкрдХреЗ рд░рд╣рддреЗ рд╣реИрдВ, рдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрд╖реНрдардХ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ,
рдЬреЛ рдЗрддрдирд╛ рд╕рд╣рдЬ рдирд╣реАрдВ рд╣реИред

рдореИрдВрдиреЗ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣рд╛рдБ рдпрд╣ рд╕реАрдзрд╛ рд╣реИ
рдХрд┐ рдореИрдВрдиреЗ рдЙрд╕ рдЯрдкрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рдПрдХ рд╡рд░реНрдЧрд╛рдХрд╛рд░ рдХреЛрд╖реНрдардХ рдпрд╣рд╛рдБ, рдПрдХ рд╡рд╣рд╛рдБ

рдлреВ <[рд╕рдВрдЦреНрдпрд╛, рд╕реНрдЯреНрд░рд┐рдВрдЧ]> ([12, '13']);

рдпрд╣рд╛рдБ рдпрд╣ рдЗрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЯрдкрд▓ рдЙрд╕ рдмрд╛рдХреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ if
рдЖрдк рдЗрд╕реЗ рдмрд╛рд╣рд░ рд╕реЗ рджреЗрдЦреЗрдВ

рдлреВ <[рд╕рдВрдЦреНрдпрд╛, рд╕реНрдЯреНрд░рд┐рдВрдЧ]>(12, '13');

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/microsoft/TypeScript/issues/5453#issuecomment-646490130 ,
рдпрд╛ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AAWYQIMTTB6JEPSQFUMTMDTRXMJD5ANCNFSM4BTBQ7DQ
.

рдореИрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдирдХреЗ рдХреИрд▓рд┐рдмрд░ рдХреЗ рдХрд░реАрдм рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдореНрдорд╛рдирдкреВрд░реНрд╡рдХ @ahejlsberg рд╕реЗ рдЕрд╕рд╣рдордд
рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдореЗрдВ, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЕрдзрд┐рдХрд╛рдВрд╢ рдЬрдЯрд┐рд▓рддрд╛ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЖрддреА рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕реА (рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдЙрдкрдпреЛрдЧреА) рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЙрдирдХреА рдЕрдкрдиреА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЬрдЯрд┐рд▓рддрд╛ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ!
рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рднрд╛рд╖рд╛ рдХреЛ рдмрдбрд╝реА, рдЕрдзрд┐рдХ рд╡реНрдпрд╛рдкрдХ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЗрди рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЛрдВ рдХреЛ рддрдм рддреБрдЪреНрдЫ рд░реВрдк рд╕реЗ рдШрдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ рдПрд╕рдЯреАрдбреА (рдкреНрд░рдХрд╛рд░) рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрдЧреА, рдЬрд┐рд╕рд╕реЗ рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрддрдирд╛ рджреВрд░ рдЬрд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ:
рдЬреИрд╕рд╛ рдХрд┐ рд╕реА ++ рдФрд░, рдХреБрдЫ рд╣рдж рддрдХ, рдЬрдВрдЧ рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рд╣реИ, рдХреБрдЫ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░, рд▓рдЧрд╛рддрд╛рд░ рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдВ рдЖрдкрдХреЛ рдореБрдлреНрдд рдореЗрдВ рдХрдИ рд╕реБрд╡рд┐рдзрд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВред
рдпрд╣ рдУрдХреИрдорд▓ рдФрд░ рд╣рд╛рд╕реНрдХреЗрд▓ (рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдл #?) рдХреЗ рд╕рдорд╛рди рд╣реИ, рдХреЗрд╡рд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрддрд░ рдкрд░, рдореВрд▓реНрдп рд╕реНрддрд░ рдкрд░ рдХрд┐рдпрд╛ рд╣реИред

рдЯрд╛рдЗрдк рд▓реЗрд╡рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реЗ рдбрд░рдиреЗ рдХреА рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЗрд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдореЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рд╕реА ++ 14/17 рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдПрдВ рдЙрдирдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдмрд╣реБрдд рд╕рд╣рдЬ рд╣реИрдВ, рдЬреЛ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд╕рд╛рдорд╛рди рдХреЗ рдХрд╛рд░рдг рд╣реИред

рдореВрд▓ рдбрд┐рдЬрд╛рдЗрди рдореЗрдВ рд╡реНрдпрд╛рдкрдХ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ред рдбрд┐рдЬрд╛рдЗрди рдХреЗ рдмрд╛рдж
рдЧрд▓рддреА рдкрд╣рд▓реЗ рд╣реА рд╣реЛ рдЪреБрдХреА рдереА, рднрд╛рд░реА рдЬреЛрдЦрд┐рдо рдЙрдард╛рдпреЗ рдмрд┐рдирд╛ рдирд┐рд░рдВрддрд░рддрд╛ рдирд╣реАрдВ рдЬреЛрдбрд╝реА рдЬрд╛ рд╕рдХрддреА
рдкреАрдЫреЗ рдХреА рдЕрд╕рдВрдЧрддрд┐ред рдореИрдВ рднрд╛рд╖рд╛ рдбрд┐рдЬрд╛рдЗрди рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рд╕рдВрджреЗрд╣ рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ:
рдПрдХ рд╕рдВрдкреВрд░реНрдг (рдЯреАрдПрд╕ рдЕрдХрд╛рджрдорд┐рдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдорд╛рдирдХреЛрдВ рд╕реЗ рдХрд╛рдлреА рджреВрд░ рд╣реИ, рдХреЛрдИ рднреА рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛
рдЗрд╕рд╕реЗ рдЕрд╕рд╣рдордд)ред рдмрд╣реБрдд рд╕рд╛рд░реА рдмрдЧ рдФрд░ рд╡рд┐рд╕рдВрдЧрддрд┐рдпрд╛рдВ рд╣реИрдВ рдЬреЛ рд╣реИрдВ
рд▓рд╛рдЦреЛрдВ рдЙрддреНрдкрд╛рджрди рдХреЛрдб рдЖрдзрд╛рд░реЛрдВ рдХреА рдиреАрдВрд╡ред рдХреЗрд╡рд▓ рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐
рдбреЗрд╡рд▓рдкрд░реНрд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рдкрд░рд┐рд╡рд░реНрдзрди рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ
рдЙрди рдмрдЧреЛрдВ рдХреЛ рдЧрд▓рддреА рд╕реЗ рдареАрдХ рдХрд┐рдП рдмрд┐рдирд╛, рдореЗрд░реА рд╡рд┐рдирдореНрд░ рд░рд╛рдп рдореЗрдВ, рдХрдорд╛рд▓ рд╣реИ
рдФрд░ рд╕рдореНрдорд╛рди рдХрд╛ рдкрд╛рддреНрд░ рд╣реИред TS рдХреА рдбрд┐рдЬрд╝рд╛рдЗрди рдЬрдЯрд┐рд▓рддрд╛рдПрдБ рдпрд╣рд╛рдБ C++ рдЬреИрд╕реА рд╣реА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА
рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрддрд░ рдмрдирд╛ рджреЗрддреА рд╣реИред

рд╢реБрдХреНрд░, рдЬреВрди резреп, реирежреиреж, резреи:рекрен рдХреЛ рдмреЗрдиреЗрдЯ рдкреАрдЯрд░ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

рдореИрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдирдХреЗ рдХреИрд▓рд┐рдмрд░ рдХреЗ рдХрд░реАрдм рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдореНрдорд╛рдирдкреВрд░реНрд╡рдХ рдЕрд╕рд╣рдордд рд╣реВрдВ
@ahejlsberg https://github.com/ahejlsberg рдХреЗ рд╕рд╛рдеред
рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдореЗрдВ, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЕрдзрд┐рдХрд╛рдВрд╢ рдЬрдЯрд┐рд▓рддрд╛рдПрдБ рд╕реЗ рдЖрддреА рд╣реИрдВрддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕рд╛рд░реА (рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдЙрдкрдпреЛрдЧреА) рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВрдЙрдирдХреА рдЕрдкрдиреА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд╢реЗрд╖-рдЖрд╡рд░рдгред

рдпрд╣ рдЬрдЯрд┐рд▓рддрд╛ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ
рд╣рд╛рд▓рд╛рдВрдХрд┐!
рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рднрд╛рд╖рд╛ рдХреЛ рдмрдбрд╝реЗ, рдЕрдзрд┐рдХ рд╡реНрдпрд╛рдкрдХ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдБ рдЬрд┐рдирд╕реЗ рдпреЗ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рддрдм рддреБрдЪреНрдЫ рд░реВрдк рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛
рдПрд╕рдЯреАрдбреА (рдкреНрд░рдХрд╛рд░) рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рд╣реЛрдЧреА
рдЖрд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░, рдЬрд┐рд╕рд╕реЗ рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди
рдЗрддрдирд╛ рджреВрд░ рдЬрд╛рдирд╛ рдЬрд░реВрд░реА рдирд╣реАрдВ рд╣реИ:
рдЬреИрд╕рд╛ рдХрд┐ C++ рдФрд░, рдХреБрдЫ рд╣рдж рддрдХ, рд░рд╕реНрдЯ рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рд╣реИ, рдХреБрдЫ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░,
рд╕реБрд╕рдВрдЧрдд рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдБ рдЖрдкрдХреЛ рдореБрдлреНрдд рдореЗрдВ рдвреЗрд░ рд╕рд╛рд░реА рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВред
рдпрд╣ рдУрдХреИрдорд▓ рдФрд░ рд╣рд╛рд╕реНрдХреЗрд▓ (рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдл #?) рдХреЗ рд╕рдорд╛рди рд╣реИ
рдореВрд▓реНрдп рд╕реНрддрд░, рдХреЗрд╡рд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрддрд░ рдкрд░ред

рдЯрд╛рдЗрдк рд▓реЗрд╡рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реЗ рдбрд░рдиреЗ рдХреА рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рд╣реИ
рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдкрдЯрдиреЗ рдХреЗ рдмрдЬрд╛рдп рднрд╛рд╖рд╛ рдореЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛
рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВред
рд╕реА ++ 14/17 рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдПрдВ рдЙрдирдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдмрд╣реБрдд рд╕рд╣рдЬ рд╣реИрдВ,
рдЬреЛ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд╕рд╛рдорд╛рди рдХреЗ рдХрд╛рд░рдг рд╣реИред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/microsoft/TypeScript/issues/5453#issuecomment-646543896 ,
рдпрд╛ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AAWYQIMWYLGGCWPTDBZJR4TRXMX4RANCNFSM4BTBQ7DQ
.

@ polkovnikov-ph рдореБрдЭреЗ рдЦреБрд╢реА рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рд╕рд╣рдордд рд╣реИрдВ :)

рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднреА рднреА рдЕрдзрд┐рдХ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреА рдУрд░ рдмрдврд╝рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдЧрд╛ред рдкреНрд░рдореБрдЦ рд╕рдВрд╕реНрдХрд░рдг рдЖрдЦрд┐рд░рдХрд╛рд░ рдПрдХ рдЪреАрдЬ рд╣реИрдВ, рдФрд░ рд╡рд┐рдХрд▓реНрдк рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрдирд╛ рд╣реИ * * рдЬреЛ рдХрд┐ рд╕реА ++ 20 рд╣реИ - рдкрд┐рдЫрд▓реЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА 2 рдкрд░рддреЛрдВ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдФрд░ рднреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рдЧрдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдПрдХ рд╕рд░рд╛рд╣рдиреАрдп рдкреНрд░рдпрд╛рд╕ рдЬрд┐рд╕реЗ рд╣рдЯрд╛рдпрд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рдореЗрдВ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИред

рдпрд╣ рд╕рдм рдЗрд╕ рд╕реВрддреНрд░ рд╕реЗ рд╣рдЯрдХрд░ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛ рд░рд╣реА

рдЙрдк-рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╢рд┐рдХреНрд╖рд╛рд╡рд┐рджреЛрдВ рдХреЛ рджрд╢рдХреЛрдВ рд▓рдЧ рдЧрдП: рдПрдордПрд▓рд╕рдм рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреЗрд╡рд▓ 6 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдкрд╣рд▓реА рдмрд╛рд░ рдЬрд╛рд░реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рджред рдпрд╣ рд╡реНрдпрд╛рдкрдХ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧреЛрдВ, рдЗрдВрдЯрд░рдлреЗрд╕, рд╕рдВрдШ рдФрд░ рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдиреАрдВрд╡ рд╣реЛ рд╕рдХрддреА рд╣реИред

рд▓реЗрдХрд┐рди рдпрд╣ рднреА рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░ рд╣реИрдВред рдореБрдЭреЗ рдФрдкрдЪрд╛рд░рд┐рдХ рдЕрд░реНрдерд╢рд╛рд╕реНрддреНрд░ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рдХрд╛рдЧрдЬрд╛рдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╛ рдкреНрд░рдЧрддрд┐/рд╕рдВрд░рдХреНрд╖рдг рдкреНрд░рдорд╛рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдиреНрдпреВрдирддрдо рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рд╡реИрдЬреНрдЮрд╛рдирд┐рдХреЛрдВ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднреА рднреА рдЙрдирдХреЗ рдЕрд╕рдлрд▓ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЛ рдЫрд╛рдкрдиреЗ рдореЗрдВ рд╢рд░реНрдо рдЖ рд░рд╣реА рд╣реИред рдпрджрд┐ рдЖрдкрдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЙрди рдкреНрд░рдореБрдЦ рдЕрд╕рдВрдЧрдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ 2040 рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрдм рдЕрдХрд╛рджрдорд┐рдХ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рд╕рд╣рдордд рд╣реЛ рд╕рдХрддрд╛ рд╣реВрдВред

рдЕрдиреНрдпрдерд╛ "рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рдЧрдИ рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА" рдХреЛ рднрд╛рд╖рд╛ рд╕реЗ рд╕рд╢рд░реНрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдХреЛрдИ рднреА рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП 60% рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рднреА рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИред (рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдХрдИ рдмрд╛рд░ рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХрдорд╛рддреНрд░ рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИред)

рдореБрдЭреЗ рдбрд░ рд╣реИ рдХрд┐ рдПрдХрдорд╛рддреНрд░ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди рдПрдХ рдЕрд▓рдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдмрдирд╛рдирд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдЯреАрдПрд╕ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА рддрд░рд╣ (рди рдХреЗрд╡рд▓ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдЦрдж рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг) рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рд░рдпрд╛рди рдкрд╣рд▓реЗ рдЯреАрдПрд╕ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдлреА рдореБрдЦрд░ рдереЗред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

DanielRosenwasser picture DanielRosenwasser  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

blendsdk picture blendsdk  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

kyasbal-1994 picture kyasbal-1994  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

bgrieder picture bgrieder  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Roam-Cooper picture Roam-Cooper  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ