ãã®ææ¡ã«ãããTypescriptã¯ãå¯å€æ°ã®ãã©ã¡ãŒã¿ãŒãåãåãé«éé¢æ°ã«åãäžããããšãã§ããŸãã
ãã®ãããªé¢æ°ã«ã¯ã concat
ã apply
ã curry
ã compose
ãããã³é¢æ°ãã©ããããã»ãšãã©ãã¹ãŠã®ãã³ã¬ãŒã¿ãå«ãŸããŸãã
Javascriptã§ã¯ããããã®é«éé¢æ°ã¯å¯å€ååŒæ°é¢æ°ãåŒæ°ãšããŠåãå
¥ããããšãæåŸ
ãããŠããŸãã
ES2015ããã³ES2017æšæºã§ã¯ãããã°ã©ããŒãé
åãšãªããžã§ã¯ãã®äž¡æ¹ã«ã¹ãã¬ããåŒæ°ãšRESTãã©ã¡ãŒã¿ãŒã䜿çšãå§ãããšããã®äœ¿çšæ³ã¯ããã«äžè¬çã«ãªããŸãã
ãã®ææ¡ã¯ãé«æ¬¡ã®çš®é¡ã«åºã¥ãåäžã®éåžžã«äžè¬çãªã¿ã€ãã³ã°æŠç¥ã§ãããã®ãŠãŒã¹ã±ãŒã¹ã«å¯ŸåŠããŸãã
ãã®ææ¡ã¯ã以äžãå«ãããã€ãã®åé¡ã«å®å šã«ãŸãã¯éšåçã«å¯ŸåŠããŸãã
Typescript-Handbookã®ãã©ãŒã¯ã§ãã®ææ¡ãæŽæ°ããŸãïŒsandersn / TypeScript-Handbook @ 76f5a75868de3fb1ad4dbed5db437a8ab61a2698
ç§ã¯sandersn / TypeScript @ f3c327aef22f6251532309ba046874133c32f4c7ã§é²è¡äžã®å®è£
ãè¡ã£ãŠãããçŸåšãææ¡ã®åçŽãªéšåãå®è£
ãããŠããŸãã
ããã¯ã以åã®ææ¡ã®ããŒã2ãïŒ5296ã«åªå
ããŸãã
ç·šéïŒå²ãåœãŠå¯èœæ§ã«é¢ããã»ã¯ã·ã§ã³ãè¿œå ããŸããã å³å¯ã«ïŒ5296ã«åã£ãŠä»£ãããã©ããã¯ããããããŸããã
curry
ãã¬ãã¥ãŒäŸ2ã€ã®åŒæ°ãæã€é¢æ°ã®curry
ã¯ãJavascriptãšTypescriptã§ç°¡åã«èšè¿°ã§ããŸãã
function curry(f, a) {
return b => f(a, b);
}
ã¿ã€ãã¢ãããŒã·ã§ã³ä»ãã®TypescriptïŒ
function curry<T, U, V>(f: (t: T, u: U) => V, a:T): (b:U) => V {
return b => f(a, b);
}
ãã ããå¯å€ååŒæ°ããŒãžã§ã³ã¯Javascriptã§ç°¡åã«èšè¿°ã§ããŸãããTypeScriptã§åãæå®ããããšã¯ã§ããŸããã
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);
}
ããã§äœ¿çšããå¯å€ååŒæ°ã¿ãã«åã®æ§æã¯ãJavascriptã®å€ã«äœ¿çšãããspreadããã³restæ§æãšäžèŽããŸãã
ããã¯ç¿åŸã容æã§ãããå泚éãšå€åŒãåºå¥ããã®ãé£ãããªãå¯èœæ§ããããŸãã
åæ§ã«ãé£çµã®æ§æã¯ãå®éã«ã¯2ã€ã®ã¿ãã«ã¿ã€ãã®é£çµã§ãããã¿ãã«æ§é ã®ããã«èŠããŸãã
次ã«ã 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]
2åç®ã®åŒã³åºãã§ã¯ã
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];
}
åå€æ°ã®ãããªå¯å€ååŒæ°ã®çš®é¡å€æ°ã¯ãéåžžã«äžéæã§ãã
åå€æ°ãšã¯ç°ãªãã1ã€ã®æäœããããŸãã
ãããã¯ãä»ã®çš®é¡ãŸãã¯å®éã®ã¿ãã«ãšé£çµã§ããŸãã
ããã«äœ¿çšãããæ§æã¯ãã¿ãã«æ¡æ£æ§æãšåãã§ãããå泚éã®å Žæã«ãããŸãã
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_ã®2ã€ã®å€æ°ãæšæž¬ããå¿
èŠããããŸãã
æãå
åŽã®åŒã³åºãã§ã¯ã 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]
ã
ãã§ãã«ãŒã¯2ã€ã®çš®é¡ã®å¢çãã©ãã«ããã¹ãããæšæž¬ã§ããªããããé£çµãããçš®é¡ãæšæž¬ããããšã¯ã§ããŸããã
function twoKinds<...T,...U>(total: [...T,string,...U]) {
}
twoKinds("an", "ambiguous", "call", "to", "twoKinds")
ãã§ãã«ãŒã¯å²ãåœãŠããã©ããã決å®ã§ããŸãã
...T = [string,string,string], ...U = [string]
...T = [string,string], ...U = [string,string]
...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
ãškindå€æ°ã®éã«ã¯äŸåé¢ä¿ããããŸããåãæ£ããããã«ã¯n === ...T.length
ãtrueã§ããå¿
èŠããããŸãã
ãããå®éã«èš±å¯ãããã¹ãã³ãŒãã§ãããã©ããã¯ããããŸããã
ã»ãã³ãã£ã¯ã¹ã¯ãã¯ã©ã¹ãšã€ã³ã¿ãŒãã§ã€ã¹ã§åãã§ãã
TODOïŒã»ãã³ãã£ã¯ã¹ã«ã¯ããããã¯ã©ã¹åºæã®ãããããã€ããããŸãã
ã¿ãã«ã®çš®é¡ã䜿çšããŠãã¹ã³ãŒãå ã®é¢æ°ã®åŒæ°ãRESTããåãæå®ã§ããŸãã
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
ã®ãã©ã¡ãŒã¿ãªã¹ãã¯ãçš®é¡...T
ã«å¯ŸããŠã€ã³ã¹ã¿ã³ã¹åãããã¿ãã«ã¿ã€ãã«å²ãåœãŠå¯èœã§ããå¿
èŠããããŸãã
æšæž¬ãããã¿ãã«ã¿ã€ãã¯[number, string]
ã§ããã€ãŸãã (a: number, b: string) => string
ã¯(...args: [number, string]) => string
å²ãåœãŠå¯èœã§ããå¿
èŠããããŸãã
å¯äœçšãšããŠãé¢æ°ã«ã¿ãã«ã®çš®é¡ããªãå Žåã§ããé¢æ°åŒã³åºãã¯ã¿ãã«ãRESTãã©ã¡ãŒã¿ãŒã«åæ£ããããšã§ãã®å²ãåœãŠå¯èœæ§ãå©çšã§ããããã«ãªããŸãã
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
ã§ãã æ®å¿µãªããããã®æŠç¥ã¯RESTãã©ã¡ãŒã¿ãŒã§ã¯æ©èœããŸããã ãããã¯é
åã«å€æãããŸãïŒ
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
ã§ãã
ããã¯ãã¿ãã«ã®æåŸã®èŠçŽ ãé
åã§ãããã¿ãã«ã®RESTãã©ã¡ãŒã¿ãŒãæã€é¢æ°ã«ç¹å¥ãªå Žåãããå Žåã«ãµããŒãã§ãããšæããŸãã
ãã®å Žåãé¢æ°åŒã³åºãã«ãããæ£ããåã®è¿œå ã®åŒæ°ãé
åãšäžèŽããããã«ãªããŸãã
ããããããã¯è€éãããŠäŸ¡å€ããªãããã§ãã
ãããã®äŸã®ã»ãšãã©ã¯ãçŸåšã®Typescriptã§åºå®åŒæ°é¢æ°ãšããŠäœ¿çšã§ããŸããããã®ææ¡ã§ã¯å¯å€ååŒæ°ãšããŠèšè¿°ã§ããŸãã
cons
ãconcat
ãçŸåšã®Typescriptã®åçš®é
åçšã«èšè¿°ã§ãããã®ããããŸãããã¿ãã«ã®çš®é¡ã䜿çšããŠç°çš®ã¿ãã«çšã«èšè¿°ã§ããããã«ãªããŸããã
ããã¯ãå
žåçãªJavascriptã®å®è·µã«ããã«å³å¯ã«åŸããŸãã
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);
TODOïŒ 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);
}
}
bind
ã call
ãããã³apply
ã¯Functionã§å®çŸ©ãããã¡ãœããã§ããããããããã®ååŒæ°ã¯ã bind
åŒã³åºããµã€ãã§ã¯ãªããé¢æ°ã®äœææã«ãã€ã³ãããå¿
èŠããããŸãã ïŒäŸãã°ïŒã ãã ããããã¯ããªãŒããŒããŒãã®ããé¢æ°ãåŒæ°ã«åºæã®åãååŸãŸãã¯è¿ãããšãã§ããªãããšãæå³ããŸããã€ãŸãããªãŒããŒããŒãåã®åéåã§ããå¿
èŠããããŸãã ããã«ãFunctionã«ã¯ååŒæ°ãçŽæ¥æå®ããã³ã³ã¹ãã©ã¯ã¿ãŒããªãããã bind
æ£ããåãæäŸããæ¹æ³ã¯å®éã«ã¯ãããŸããã TODOïŒããã«äŸãè¿œå ããŸãã ãã®åé¡ã¯å¿
ãããå¯å€ååŒæ°é¢æ°ã«åºæã®ãã®ã§ã¯ãªãããšã«æ³šæããŠãã ããã+1ãããã¯TypeScriptã®é¢æ°åããã°ã©ãã³ã°ã«éåžžã«åœ¹ç«ã¡ãŸãïŒ ããã¯ããªãã·ã§ã³ã®åŒæ°ãŸãã¯RESTåŒæ°ã§ã©ã®ããã«æ©èœããŸããïŒ ããå
·äœçã«ã¯ã compose
é¢æ°ã¯ãRESTåŒæ°ãŸãã¯ãªãã·ã§ã³ã®åŒæ°ãæã€é¢æ°ã§äœ¿çšã§ããŸããïŒ
ããèŠç¹ãã ã¿ãã«ã¯åãªããªããžã§ã¯ãã§ãããè¿œå ã®ã¡ã³ããŒãèš±å¯ãããããèš±å¯ãããæå°ã®ã¿ãã«ã¿ã€ããoptional-paramé¢æ°ã«å²ãåœãŠãããšãã§ãããšæããŸãã ããããããã¯çæ³çã§ã¯ãããŸããã 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ã«é¢é£ããŠããŸãïŒãããŠæºããã§ãããïŒã TypeScriptã§äœæã¿ã€ãAPIãå®è£ ããããšããŸãããããã®ææ¡ã«èšèŒãããŠããå¶éã®ããã€ããåé¿ããå¿ èŠããããŸãã ããã¯ç¢ºãã«ãããã®åé¡ã®ããã€ãã解決ããã§ãããïŒ
ç¹ã«composeã®ãããªãã®ã§ã¯ããã®ãããªã¿ãã«ã¿ã€ããæ°žç¶åããã®ã§ã¯ãªãããããŒãžããããå Žåãããããã§ãã äŸãã°ïŒ
function compose<T, ...U>(base: T, ...mixins: ...U): T&U {
/* mixin magic */
}
ãŸããå€ãã®äŸã§ã¯ãããªããã£ãã䜿çšããŠããŸãã ç¹ã«ç«¶åãããå Žåãããè€éãªæ©èœãã©ã®ããã«æ©èœãããšæããŸããïŒ
æ®å¿µãªãããã¿ãã«ã®çš®é¡ã®å¯äžã®åææŒç®åã¯[T,...U]
ã§ããããããã®ææ¡ã¯ãã®ãŸãŸã§ã¯ïŒ3870ãŸãã¯ååæã«å¯Ÿå¿ããŠããŸããã ãããT + ...U
ïŒåã«äœãèµ·ãããããããã瀺ããŸãïŒãšæžãããšãã§ããŸãããïŒ3870ãšåæ§æã©ã€ãã©ãªã«ã¯T & ...U
ãå¿
èŠã§ãã ç§ã¯ãããå¯èœãããããªããšæãããç§ã¯æåã®ïŒ3870ãã@JsonFreemanãããš@jbondcã®èããç解ããå¿
èŠããããŸãã ãããã©ã®ããã«æ©èœããããç解ã§ããã°ãææ¡ãæ¡å€§ããŸãã
泚ïŒåçã®å€æ¡æ£æ§æã®ããã«èŠãããããæ§æ[...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 ã -
ã¯è¯ãèãã®ããã§ãã æ°ããã¿ã€ãã®æŒç®åã1ã€ãã€å°å
¥ããå¿
èŠããããšæãã®ã§ãããã§ã¯ããã念é ã«çœ®ããŠããŸãããããã§ã¯èª¬æããŸããã &
ãš+
äž¡æ¹ãæ°ããåãäœæããŸããã &
ã¯äº€å·®åãäœæãã +
ã¯æ°ããã¿ãã«åãäœæããŸãïŒãããæ§æ[T,...U]
ã奜ãçç±ã§ãïŒ T + ...U
[T,...U]
代ããã«[T,U]
ãã§ã«åã«å¯ŸããŠãããè¡ã£ãŠããããïŒã
@JsonFreeman lã¯ãçš®é¡ãã©ã¡ãŒã¿ãç¹°ãè¿ããŠ2ã€ã®ããšã®ãããããå®è¡ããŠãåé¡ãªããšæããŸãã
f(['hello', 1], [1, false]): [string | number, number | boolean]
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ã€ãããªããããïŒ1ïŒãïŒ2ïŒãç¹ã«äœ¿çšã§ããªããŠããå®éã®ã³ãŒãã«å€§ããªåœ±é¿ãäžããããšã¯ãªãã¯ãã§ãã
äžèšã®äŸã§ã¯ã curry
æãé£ããæšè«ããããšã§ãã-ããªãã¯ã¹ãããããå¿
èŠãf: (...args:[...T,...U]) => V
æšæž¬ãã ...ts:...T
ããã®åŸãæ»ã£ãŠèšå®...U
äœã«f
ã®ãã©ã¡ãŒã¿ãã...T
ãæ¶è²»ããåŸã«æ®ã£ãã
ç§ã¯ããïŒsandersn / TypeScript @ 1d5725dïŒã®ãããã¿ã€ãã³ã°ãéå§ããŸãããããŸã ããã»ã©é²ãã§ããŸããã ãããããŸããããã©ããäœãèãã¯ãããŸããïŒ
ç§ã¯ãã»ãã³ãã£ã¯ã¹ãæ確ã§ãªããã®ïŒåãæ¡æ£åãã©ã¡ãŒã¿ãŒãžã®ç¹°ãè¿ãã®æšè«ãªã©ïŒãçŠæ¢ããåŽã§èª€ããç¯ããŸãã ããã¯äžèšã®ç§ã®æžå¿µãåãããŸãã
ã«ã¬ãŒãã¿ã€ãããã®ã«è¯ãã¡ã«ããºã ãæãã€ããªãã ãææã®ãšããã ...T
åŒæ°ã䜿çšããã«ã¯ãæåã®é¢æ°ã®ãã©ã¡ãŒã¿ãŒãªã¹ããã¹ãããããŠãæ®ã£ãŠãããã®ã確èªããå¿
èŠããããŸãã ãªã¹ãã®æåŸã§ã¯ãªãå Žåãæ¡æ£åãã©ã¡ãŒã¿ãŒãžã®æšè«ã延æããããã®ããªã·ãŒãå¿
èŠã«ãªããŸãã ä¹±éã«ãªãå¯èœæ§ããããŸãã
ããã¯èšã£ãŠããããã¯è©ŠããŠã¿ã䟡å€ããããšæããŸãã ãã®æ©èœã«å¯ŸããéèŠã¯é«ãã§ãã
åãã³ã³ããã¹ãã§çºçããè€æ°ã®ã¿ãã«ã®çš®é¡ãã¹ãããããå¿
èŠããããšæããŸãïŒããšãã°ã (...T,string,...U) => V
ãããªãããã¬ãã«ããŸãã¯[...T,...U,...T]
ããã«é£çµããããã®ïŒã 次ã«ãã¹ããããããçš®é¡ã«å¯ŸããŠè€æ°ã®ãã¹ãäœæããŠããã§ã«æšæž¬ãããçš®é¡ãåé€ãããŸã ãããŸããªçš®é¡ãåã¹ãããããããšãã§ããŸãã æšè«ã«äœ¿çšã§ããåäžã®çš®é¡ããªãå Žåã¯ãåæ¢ããŠãšã©ãŒãè¿ããŸãã
ã ãããããã è€éã
åæ§ã®åé¡ããã€ã³ã¹ãã¬ãŒã·ã§ã³ãåŒãåºãããšãã§ãããããããŸããã ããã¯ãå®éã«ã¯ãåéåãŸãã¯å
±ééšåãæšæž¬ããåé¡ã«ããã¶ã䌌ãŠããŸãã function f<T>(x: T | string[])
ããã«ãæšè«ã³ã³ããã¹ãã®ã¡ã³ããŒã§ããåãã©ã¡ãŒã¿ãŒãå«ãå
±çšäœåãæšè«ããå ŽåãTãæšè«ãããã©ããã¯ããããŸãããå
±çšäœåã®æå³ãããè¡šçŸã¯æ¬¡ã®ããã«ãªã£ãŠããå¯èœæ§ããããŸãã string[]
ã ãããã£ãŠãtypescriptã¯æåã«ä»ã®ãã¹ãŠã®æ§æèŠçŽ ãæšè«ãã次ã«æšè«ãè¡ãããªãã£ãå Žåã¯Tãæšè«ããŸãã
亀差ç¹ã®å ŽåãåŒæ°ã®ã¿ã€ããç°ãªã亀差ç¹ã®æ§æèŠçŽ ã«åå²ããªããã°ãªããªãå¯èœæ§ããããããããã«å°é£ã«ãªããŸãã Typescriptã¯äº€å·®åããŸã£ããæšæž¬ããŸããã
ã¿ãã«ãã·ãŒã±ã³ã¹ã®æåŸã®ã¿ã€ãã§ããå Žåã«ã®ã¿ãã¿ãã«ã®æ¡æ£ãèš±å¯ããå Žåã¯ã©ããªããŸããïŒ ãããã£ãŠã [string, ...T]
ã¯èš±å¯ãããŸããã [...T, string]
ã¯èš±å¯ãããŸãããïŒ
ç§ãæ£ããç解ããŠããã°ãããã¯å®éã«TypeScriptã®ããã¯ã¹ã€ã³ã¹ããŒãªãŒã解決ããã§ãããã ç§ã¯ãã®ç解ã§æ£ããã§ããïŒ
å€åã äŸãæããŠããã ããŸããïŒ ç§ã¯ããã¯ã¹ã€ã³ãã¿ãŒã³ã«å ªèœã§ã¯ãããŸããã
å¯å€ååŒæ°ã®çš®é¡å€æ°ã®æ§æã¯... Tã§ããããã§ãTã¯ãæ £äŸã«ããåäžã®å€§æåã§ããèå¥åããŸãã¯Tã®åŸã«PascalCaseèå¥åãç¶ããŸãã
ã¿ã€ããã©ã¡ãŒã¿èå¥åã®å Žåã¯éçºè ã«ä»»ããããšãã§ããŸããïŒ
@ aleksey-bykov + 1ã ãããã¹ãã§ã¯ãªãçç±ãããããŸããã
Haskellã®ããã¯ã°ã©ãŠã³ããæã€éçºè ã¯ãããããã ããã°å¹žãã§ãã
ç³ãèš³ãããŸãããããã®æã¯ãããŸãã«è§£æãããå¯èœæ§ããããŸãã ç§ã¯ããŸãã¯ããå³å¯ã«è§£æããããšãæå³ããŸããïŒãæ £äŸã«ããïŒåäžã®å€§æå|| Tã®åŸã«PascalCaseèå¥åãç¶ãïŒãã ç§ã¯èå¥åã®å€§æåãšå°æåãå¶éããããšãææ¡ããŠããã®ã§ã¯ãªããæ £äŸãææããŠããã ãã§ãã
ãããããã®äŸ¡å€ã«ã€ããŠã¯ã_I_ã¯Haskellã®ããã¯ã°ã©ãŠã³ããæã£ãŠãããç§ãæžããŠããèšèªã®æ £ç¿ãç Žãã®ã¯å¥œãã§ã¯ãããŸããã
è±ç·ããŠãã¿ãŸããã ç§ã®æåŸã®äžæè°ãªè³ªåïŒããªããç§ã«å°ããŠãæ§ããªãã®ãªãïŒã¯ãå£ãããããããªãTypeScriptã®ãæ £ç¿ããšã¯äœã§ããããããŠèª°ãå¿é ããŠããŸããïŒ
@sandersn
T & ...U
T & U & V & ...
æå³ãããšä»®å®ãããšãããã¯checkãšå
¥åããå¿
èŠããããŸãïŒããã¯çŽæçãªåäœã§ãïŒã
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
}
@ aleksey-bykovç§ã話ããŠããèŠåã¯ãåãã©ã¡ãŒã¿ãŒèå¥åã®å Žåã§ãã 誰ãå¿é ã§ããïŒ ãããŸã§ã«èŠãããšã®ãªãæ°ããTypescriptã³ãŒããèªãŸãªããã°ãªããªã人ã -æ £ç¿ã¯ãæ°ããèªè ãæ°ããã³ãŒããããéãç解ããã®ã«åœ¹ç«ã¡ãŸãã
@sandersn @ aleksey-bykovãå°è±¡ã«æ®ã£ãã®ã¯ã以äžã¯_æ§æçã«_ç¡å¹ã«ãªããšããããšã§ããã
function assign<a, b, ...cs>(x: a, y: b, ...zs: ...cs): a & b & ...cs;
@isiahmeadows &
ããã³|
çš®é¡ã«å¯Ÿããæäœã¯ããã®ææ¡ã§ã¯ã«ããŒãããŠããŸããããæªè§£æ±ºã®è³ªå/å°æ¥ã®äœæ¥ã«è¿œå ããå¿
èŠããããŸãã çŸåšãææ¡ãããŠããæŒç®åã¯é£çµã®ã¿ã§ãïŒ [THead, ...TTail]
ã
1ã€ã®éãã¯ãé£çµã«ãã£ãŠã¿ãã«åãçæãããã®ã«å¯Ÿãã &
ãš|
ã¯ããããå
±ééšåãšå
±çšäœåãçæããããšã§ãã
@sandersn TypeScriptã§ã®ç§ã®assign
äŸã¯ãããã§å€æŽããã®ã¯ç°¡åã§ãã
ããã§ãïŒ
@isiahmeadows亀差ç¹ã¯ãäžè¬ã«èŸæžã®é£çµã§ã¯ãããŸããã ããã¯ããªããžã§ã¯ãã¿ã€ãã®å ±ééšåã«ã®ã¿åœãŠã¯ãŸããŸãããããšãã°ãŠããªã³ã®å ±ééšåã«ã¯åœãŠã¯ãŸããŸããã ãŠããªã³ã¯ããªããžã§ã¯ãã«å ±éããããããã£ãååŸããããšãšåãã§ã¯ãããŸããã ãã®2ã€ã¯ããããã«ååšããäžé£ã®å€ã«ãã£ãŠããããç¹åŸŽä»ããããŸãã
@sandersnååŒæ°ã®æšè«ãšå¯å€ååŒæ°ã®çš®é¡ã«ã€ããŠå°ãæ··ä¹±ããŠããŸãã ããã§äœãæšæž¬ããå¿ èŠããããŸããïŒ
function foo<...T>(...rest: ...T): ...T { }
foo('str', 0, [0]);
çµæã¯[string, number, number[]]
ã§ããïŒ ã€ãŸããåè£è
ãå·Šããå³ã®é åºã§è¿œå ããååŒæ°ã®æšè«ã«äŸåããå¿
èŠããããŸãããããã¯ç°¡åãªä»®å®ã§ã¯ãããŸããã ãŸããåã·ã¹ãã ãæšè«åè£ã®ãªã¹ãããŠãŒã¶ãŒã«è¡šç€ºããã®ã¯ãããåããŠã§ãã
ããã¯å®éšç/åæã®ææ¡ã§ãããRESTãã©ã¡ãŒã¿ãŒã®...T
æ§æã«ã€ããŠèª¬æããããšã¯ã§ããŸãã ç§ã®èŠ³ç¹ããã¯ãããã¯å®éã«ã¯æ©èœããŸããã
ãããã£ãŠãææ¡ãããæ§æã¯æ¬¡ã®ãšããã§ãã
declare function f<...T>(...a: ...T);
RESTãã©ã¡ãŒã¿ãŒã®æ¢åã®æ§æãšæ¯èŒããŠã¿ãŸãããã
declare function f(...a: number[]);
ãããã£ãŠãRESTåŒæ°ããã£ããããa
ãã©ã¡ãŒã¿ãŒã®ã¿ã€ãã¯number[]
ã§ããããããããé
åã§ããããšãæ確ã«ç解ã§ããŸãã é¡æšãããšãææ¡ã®...T
ãé
åãè¡šããŠãããšæšæž¬ã§ããŸãã ããããããã¯ããŸãæçœã§ã¯ãããŸããã
次ã«ãããå¶éçãªRESTãã©ã¡ãŒã¿ãŒãå®çŸ©ã§ãããšããŸãããã
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
æŠå¿µã§RESTãã©ã¡ãŒã¿ãŒãå®çŸ©ããããã®ç§ã®æ§æïŒ
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
æšæºã®RESTãã©ã¡ãŒã¿ãŒã«åããã®ãé©çšããå Žå
function f(...a: number[]): number[] { return a; }
a
ã¿ã€ãã¯ã眲åã§å®çŸ©ããããã®ãšåãnumber[]
ïŒãªã¿ãŒã³ã¿ã€ãå¥ïŒã§ãã
@isiahmeadowsã¯ãã function f(...a: [number, string])
ã¯æ©èœããŸããã ç§ã¯ãRESTãã©ã¡ãŒã¿ãŒãã©ã®ããã«æ±ãããšãã§ãããã«ã€ããŠã®èããéçºããŸããã
ã ãããããã«é²ãã§ãã ããã åãã©ã¡ãŒã¿ãŒãæ瀺çã«å®çŸ©ããããã«ã次ã®æ§æãææ¡ãããŸããã
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æåçããïŒç§ã®æèŠã§ã¯ïŒèŠèŠçãªãã€ãºãå°ãªããªããŸãã
@ aleksey-bykovç§ã¯å®éã«ã¯ããã«ã€ããŠå察æèŠã§ãã ããã¯æ¢åã®RESTãã©ã¡ãŒã¿ãŒæ§æã«é©åããªããããäžèŠããã ãã§ããããã«ãããšæããŸãã
æ®ãã®é
åãã©ã¡ãŒã¿ãŒã¿ã€ããšããŠã®[...T]
/ T
ã¯ãç§ã«ãšã£ãŠã¯ããã«åªããŠããããã§ãã ããäžåºŠãé
åãšãã®spradæŒç®åãšæ¯èŒããŠãã ããã
| é
å| ã¿ã€ãïŒææ¡ããïŒ| ã¿ã€ãïŒç§ã®æŽæ°ïŒ|
| --- | --- | --- |
| 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ã®æ¹ãèŠæ ããããŸãã ã¿ã€ããè¡šããªã¹ãã¯éåžžã«ããããã«èãããŸãããã¿ã€ããããLispã§ããããã»ã©é ãã«ã¯è¡ããŸããïŒååæ§ã¿ã€ãã誰ãïŒïŒsmile :)ã
ç§ã¯çŽç²ãã®é åãæããŸãããå®çšçãªåŽé¢ãèŠãŠããŸãã ãªã¹ãã¯ãããèªäœã§æ¯èŒçç°¡åã«å®è£ ããããšãã§ããŸãããä»ã®èšèªã«ã¯é©åããŸããã ããã¯ãJavaïŒèšèªïŒã§ã¢ãããå®è£ ããããCã§ã©ã ããå®è£ ãããããå€ãã®è©Šã¿ãšã»ãšãã©åãã§ãããããã¯åžžã«ä¿¡ããããªãã»ã©éãããã¯ãªãã®ã«ãªããŸãã
@sandersnåè£è ã®ãªã¹ããå ¬éããããšã§ãç§ãäœãæå³ããã®ãã説æããããšè©Šã¿ãããšãã§ããŸãã ååŒæ°ã®æšè«ã«ãããååãã©ã¡ãŒã¿ãŒã®åè£ã®ãªã¹ããçæãããŸãã 次ã«ãããããã®åè£ãä»ã®ãã¹ãŠã®ã¹ãŒããŒã¿ã€ãã§ãããã©ããã確èªããããã§ããå Žåã¯ããã®åè£ãåè ã§ãã ãããã£ãŠã次ã®äŸã§ã¯ïŒ
function foo<T>(a: T, b: T): T {}
foo(["hi", 0], ["", ""]);
åŒæ°ãå
¥åãããåãã©ã¡ãŒã¿ãŒã«æšæž¬ãããŸãã (string | number)[]
ãšstring[]
2ã€ã®åè£ãçæãããŸãã ããããæåã®ãã®ã¯2çªç®ã®ã¹ãŒããŒã¿ã€ãã§ãããããåã¡ãŸãã ãã®çµæããŠãŒã¶ãŒã¯string[]
ãåçã«åã£ãŠããããšã«æ°ä»ãããšT
ã«ã¯1ã€ã®æšè«ããããä»ã®ãã¹ãŠã®åè£ã¯è¡šç€ºãããŸããã ããã¯ããŠãŒã¶ãŒã«ã¯èŠããªããã®ã2ã€ããããšãæå³ããŸããã€ãŸããåè£è
ã®é åºãšåè£è
ã®å€æ§æ§ã§ãã
...T
瀺ãããã¿ãã«å
ã®èŠçŽ ã®ãªã¹ããšããŠåè£ãªã¹ãã«äŸåããŠããå Žåãå€é床ã«é¢ããåé¡ããããŸãã
function foo<...T>(...rest: ...T): ...T
foo(0, 1);
ç§ãç解ããŠããããã«ãããªãã®ææ¡ã®æå³ãèããã°ãTã«ã€ããŠ[number, number]
ãæšæž¬ããããšæãã§ãããã ãã ãã httpsïŒ//github.com/Microsoft/TypeScript/blob/master/src/compiler/checker.ts#L6256ã«å«ãŸãããã§ãã¯ã€ã³ã©ã€ã³ãããããã number
åè£ã¯1åã ãè¿œå ããã T
ã¯[number]
ãšããŠæšæž¬ãããŸãã ããã¯ç§ã話ããŠããå€å
æ§ã®åé¡ã§ãã
é çªã¯å·Šããå³ã§ãã ãã ããè€æ°ã®ãã¹ããããã³ã³ããã¹ãã§åæå®ãããé¢æ°åŒãåŒæ°ã«å«ãŸããŠããå ŽåãåŒæ°ã¯ååŠçãããŸãã ã³ã³ããã¹ãã§åæå®ãããé¢æ°åŒãå«ãåŒæ°ãnåããå ŽåãåŒæ°ã¯n +1åæž¡ãããŸãã äŸãšããŠã¯ãArray.prototype.reduceããããŸããããã§ã¯ãinitialValueãã©ã¡ãŒã¿ãŒãå³åŽã«ããã«ãããããããã³ãŒã«ããã¯ã®åã«å¹æçã«åæå®ãããæšæž¬ãããŸãã ãããã£ãŠã次ã®ãããªãã®ãææ¡ã®åé¡ã«ãªãå¯èœæ§ããããŸãã
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]
ãšããã§ã x => x
ã{ <T>(x: T): T; }
åã§ãããšæšæž¬ã§ããŸããïŒ
@Igorbek補é ã¿ã€ãã®ãã©ã¡ãŒã¿ãŒã«ã€ããŠã®ããªãã®ææ¡ïŒå°ãªããšããããã©ã®ããã«å®è£
ãããŠãããã«é¢ä¿ãªããçŽæãšããŠïŒã¯ãããè¡ãæ£ããæ¹æ³ã ãšæããŸãã T
ã®ã¿ã€ãã®ã·ãŒã±ã³ã¹ãæšæž¬ã§ããŸããããã§ãã·ãŒã±ã³ã¹å
ã®åèŠçŽ ã«ã¯ã€ã³ããã¯ã¹ãšåè£ã®ãªã¹ãããããŸãïŒããã¯ããªããè¿°ã¹ãããšãå®è£
ããå¥ã®æ¹æ³ã§ãïŒã
ããããç§ã®èšãããããšã¯ãæšè«åè£ãªã¹ããæšè«ãããã¿ãã«ãšããŠåå©çšããå Žåããããèªç¶ã«èµ·ããããšã§ã¯ãªããšæããŸãã æ£ããããšãå®çŸããã«ã¯ãæ瀺çãªã¡ã«ããºã ãå¿ èŠã«ãªããŸãã
{ <T>(x: T): T; }
ã«ã€ããŠã®ããªãã®ãã€ã³ãã«ã€ããŠx => foo(x)
ãããªãã®ãã¿ã€ãããããšã«ããŸãäžè¬åãããŸããã foo
éè² è·è§£æ±ºãè¡ãã«ã¯ã x
ã®ã¿ã€ããç¥ã£ãŠããå¿
èŠããããŸãã
ã¿ã€ããã§ãã«ãŒæšè«èŠåãšã®æŠãããã®å°ããªäžæ©ã
æ§æã«ã€ããŠã®ã³ã¡ã³ã/ææ¡ããããŸãã äžè²«ããŠãããçžäºã«æä»çãª2ã€ã®ãªãã·ã§ã³ããããšæããŸãã
ãã®ãã©ãŒã ãéžæããå ŽåïŒ
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]
...
ãããã£ãŠãããã¯çã®ã¬ã¹ããã©ãŒãã«ã¿ã€ãã«ãªããŸãã ãããã¯ãæ£åŒãªã¿ã€ããã©ã¡ãŒã¿ã»ã¯ã·ã§ã³ã®æåŸã®äœçœ®ã§ã®ã¿äœ¿çšããå¿ èŠããããŸãã
(...args:[string, number]) => boolean IS EQUIVALENT TO (s: string, n: number) => boolean
ãã®å Žåããã©ãŒãã«ã¿ã€ãã®ãã©ã¡ãŒã¿ã»ã¯ã·ã§ã³ã«ã¯åžžã«åºå®æ°ã®ã¹ãããããããŸãã
function f<T>(...args: T): T {
return args;
}
ããããã®æ¡ä»¶ãæºããããå ŽåãTã¯ã¿ãã«åã§ããå¿ èŠããããšæšæž¬ããŸãã
ãããã£ãŠãæ£åŒãªåãã©ã¡ãŒã¿ã»ã¯ã·ã§ã³ã§çç¥èšå·ã䜿çšããå¿ èŠã¯ãããŸããïŒåãã§ãã«ãŒããªããŠã_æ§æçã«_æšæž¬ã§ããŸãïŒ
ãã®å Žåãç§ãã¡ã¯ãŸãæžãããšãã§ããŸã
function f<T>(...args: [...T]): [...T] {
return args;
}
ããããããã¯åé·ã§ãã
å人çã«ã¯ãåŸè ãTypeScriptã«å®è£ ãããããšãæãã§ããŸãã @ JsonFreeman ã@ sandersnïŒ
@Artazorè¡šçŸèŠçŽãããšã2ã€ã®ã¢ãããŒããå¿ ãããåçã§ãããšã¯æããŸããã 2ã€ç®ã¯ãRESTåãã©ã¡ãŒã¿ãŒãã¿ãã«åå ã«æ¡æ£ããæ©èœãåããŠããŸããã1ã€ç®ã¯ããã§ã¯ãªãããã§ãã
ãžã§ããªãã¯åã®åç §ã®å ŽåãRESTåãã©ã¡ãŒã¿ãŒãã©ãã§æ§æçã«ã©ã®ããã«äœ¿çšãããã決å®ããã ãã ãšæããŸãã ããã¯ãåã·ãŒã±ã³ã¹ïŒã¿ãã«ãã·ã°ããã£ããžã§ããªãã¯ååç §ïŒããšããã¹ãŠã®åã³ã³ã¹ãã©ã¯ã¿ãŒã«å¯ŸããŠæ±ºå®ããå¿ èŠããããŸãã
äžè¬çãªçœ²åã®å ŽåãååŒæ°ã®æšè«ã®ããã«ãããè€éã«ãªããŸãã 次ã®å Žåã¯ã©ããªããŸããã
function callback(s: string, n: number): void { }
declare function foo<...T>(cb: (...cbArgs: T) => void, ...args: T): [...T];
foo(callback, "hello", 0, 1);
fooã¯äœãè¿ããŸããïŒ ç§ã®èšãããããšã¯ããžã§ããªãã¯ã«ãŒã«ã¯ãžã§ããªãã¯åãšãžã§ããªãã¯ã·ã°ããã£ã§åãã§ãããšäººã ãæåŸ ããŠãããšããããšã§ããããžã§ããªãã¯åãããè¡šçŸåè±ãã«ããå ŽåãååŒæ°ã®æšè«ã«ã¯ãããåŠçããæ¹æ³ãå¿ èŠã§ãã ããã¯ãååŒæ°ã®æšè«ãé£ããã±ãŒã¹ãæ£åŒã«èå¥ãããããã®å Žåã«ãŠãŒã¶ãŒã«æ瀺çãªååŒæ°ãæž¡ãããã«èŠæ±ããã ãã®åé¡ã§ããå¯èœæ§ããããŸãã
ç§ã®æèŠã§ã¯ãããªãã®éžæè¢1ã®æ¹ãè¯ããšæããŸãã å人çã«ã¯ãã¿ãã«åãRESTãã©ã¡ãŒã¿ãŒãšããŠäœ¿çšããããšã¯èŠãŠããŸããã Restãã©ã¡ãŒã¿ãŒã¯å¯å€é·ã§ãããšæ³å®ãããŠãããããé ååãŸãã¯RESTåãã©ã¡ãŒã¿ãŒã®ã¿ãèš±å¯ããå¿ èŠããããšæããŸãã ãŸããåã·ã¹ãã ã«ãã§ã«ååšãããã®ã«é¢é£ä»ããããŠããªããåã®æœè±¡çãªã·ãŒã±ã³ã¹ã§ããRESTåãã©ã¡ãŒã¿ãŒã®æŠå¿µãæ°ã«å ¥ã£ãŠããŸãã
ã¿ãã«ã«é¢ããç§ã®å²åŠã¯ãã¿ãã«ã¯é·ããããã£ãŠããé åå€ã®ãµãã»ãããè¡šããšãããã®ã§ãã ãããã®é åå€ã¯å®éã®ã©ã³ã¿ã€ã ãšã³ãã£ãã£ã§ãã åã®æœè±¡çãªã·ãŒã±ã³ã¹ïŒããšãã°ã眲åå ã®ãã©ã¡ãŒã¿ãŒã®ã·ãŒã±ã³ã¹ïŒãè¡šãäžçš®ã®åã·ã¹ãã ããã€ã¹ãšããŠãããã䜿çšãããšããèãã¯å¥œãã§ã¯ãããŸããã ãã ããRESTã¿ã€ãã®ãã©ã¡ãŒã¿ãŒãã¿ãã«ã«åæ£ã§ãããã©ããã¯å¥ã®è©±ã§ãã
ã¿ãã«ã¯ãã匷åã§ãããå€ãã®ãŠãŒã¹ã±ãŒã¹ã解決ã§ãããããã¿ãã«ã®ææ¡ã奜ãã§ããã¿ãã«ã¯åãªãé åã§ãããRESTãã©ã¡ãŒã¿ãŒã䜿çšããŠé¢æ°ãåŒã³åºããšãé åãæ¡æ£ã§ãããããã¿ãã«ãRESTãã©ã¡ãŒã¿ãŒãšããŠæ¡æ£ã§ããããšãéåžžã«çŽæçã§ãã ããããã°ãåã·ã¹ãã ã¯ç§ã®ã³ãŒãã®ç解ãšããããäžèŽããã§ãããã
@JsonFreemanã®å Žåãfooã¯[string, number, number]
ãè¿ããŸããããã¯ã ...args
ããæšæž¬ãããæšæž¬ãããcbã¿ã€ãã¯(string, number, number) => void
ãããæž¡ãããã³ãŒã«ããã¯ã¯æåŸã®åŒæ°ãç¡èŠããŸãã TSãšJSã®äž¡æ¹ã§éåžžã«äžè¬çã§ãã
åã®æœè±¡çãªã·ãŒã±ã³ã¹ãè¡šãããã«ããããäžçš®ã®åã·ã¹ãã ããã€ã¹ãšããŠäœ¿çšãããšããèãã¯å¥œãã§ã¯ãããŸãã
ããã¯ãŸãã«åœŒããäœã§ãããã§ããJSã¯ã¿ãã«ã«ã€ããŠç¥ããŸãããTSã ãã§ãã 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]
ã¿ãã«ã§RESTåãã©ã¡ãŒã¿ãŒãæ¡æ£ãããšããã¢ã€ãã¢ãåŸåãã«ããããšãã§ããŸããã ããããRESTåãã©ã¡ãŒã¿ãŒãæé»çã«ã¿ãã«ãšããŠè§£éããå¿ èŠããããã©ããã¯ããããŸããã @Pajnã®äŸã¯ã
@Igorbekæåã®äŸã®ãããŸããã«ã€ããŠã¯æ£ããã§ãã ãã ãã3çªç®ã®äŸã«ãåé¡ããããŸãã number, string
ãããªã·ãŒã±ã³ã¹ãäžãããããšã眲åã®2ã€ã®å¯èœãªã€ã³ã¹ã¿ã³ã¹åããããŸãã ã€ãŸãã (arg1: number, arg2: string) => [number, string]
ãš(arg1: [number, string]) => [number, string]
ïŒäŸã®ããã«æé»ã®ã¿ãã«è§£éãæ¡çšïŒã§ãã
æé»ã®ã¿ãã«è§£éã«é¢ãããã1ã€ã®å¥åŠãªç¹ã¯ãããã§ãã number, string
ã«ã€ã³ã¹ã¿ã³ã¹åãããŠããRESTåãã©ã¡ãŒã¿ãŒTããããšããŸãã ããã§ãããããååŒæ°Foo<T>
ãšããŠæž¡ããšããŸãã Foo<...T>
ãFoo<number, string>
ããã®ã«å¯Ÿããããã¯Foo<[number, string]>
ãšããŠè§£éãããŸããïŒ ããã«ã¯ãspreadæŒç®åãåã·ã¹ãã ã«æ¡åŒµããããšã«ãªããããè°è«ããããŸãã ããããããã§ãã¿ãã«ããŒãžã§ã³ã¯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)
æåã®äŸã¯ãFunctionïŒapplyã«çŽæ¥é¢é£ããŠããŸãïŒ
ãšã©ãŒïŒã2çªç®ã¯ã³ã³ãã€ã«ã«å€±æããæããã§ãªãééãã§ãã
Intellisenseã§æ€åºããã®ã¯ç°¡åã§ã¯ãããŸããã
æ¥ã2016幎2æ28æ¥ã«ã¯ãåå3æ04åãžã§ã€ãœã³ã»ããªãŒãã³[email protected]ã¯æžããŸããïŒ
æé»ã®ã¿ãã«è§£éã«é¢ãããã1ã€ã®å¥åŠãªããšã¯ã次ã®ãšããã§ãã
æ°å€ãæååã«ã€ã³ã¹ã¿ã³ã¹åãããRESTã¿ã€ããã©ã¡ãŒã¿TããããŸãã
ããŠãããããååŒæ°ãšããŠæž¡ããšããŸããããFooã ããã¯
Foo <[numberãstring]>ãšããŠè§£éãããŸãããFoo <... T>ã¯Fooã§ãæåå>ïŒ â
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -189817561
ã
@JsonFreeman
ãã ãã3çªç®ã®äŸã«ãåé¡ããããŸãã
number, string
ãããªã·ãŒã±ã³ã¹ãäžãããããšã眲åã®2ã€ã®å¯èœãªã€ã³ã¹ã¿ã³ã¹åããããŸãã ã€ãŸãã(arg1: number, arg2: string) => [number, string]
ãš(arg1: [number, string]) => [number, string]
ïŒäŸã®ããã«æé»ã®ã¿ãã«è§£éãæ¡çšïŒã§ãã
æãããªç§ã®3çªç®ã®äŸãããããã¯(...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]>;
æé»ã®ã¿ãã«è§£éã«é¢ãããã1ã€ã®å¥åŠãªç¹ã¯ãããã§ããããšãã°ãRESTã¿ã€ããã©ã¡ãŒã¿ãŒ
T
ãnumber, string
ã«ã€ã³ã¹ã¿ã³ã¹åãããŠãããšããŸãã
T
ã¯ãçã®ã¿ãã«ã§ããããã number, string
ã€ã³ã¹ã¿ã³ã¹åã§ããŸããã [number, string]
ã§ããå¿
èŠããããŸãã
ããã§ãããããååŒæ°
Foo<T>
ãšããŠæž¡ããšããŸããFoo<...T>
ãFoo<number, string>
ããã®ã«å¯Ÿããããã¯Foo<[number, string]>
ãšããŠè§£éãããŸããïŒ
NSã ãã ãã <...T>
䜿çšããããšã¯ããããã説æãããã®ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯åé·ã«æããŸãïŒRESTåŒæ°ã®äœçœ®ä»ããããåããã£ããããŸãïŒã ããã«ãããããããç§ãã¡ããããæã£ãŠãããšããŸãããã
ããã«ã¯ãspreadæŒç®åãåã·ã¹ãã ã«æ¡åŒµããããšã«ãªããããè°è«ããããŸãã ããããããã§ãã¿ãã«ããŒãžã§ã³ã¯
Foo<[...T]>
ãšããŠè¡šãããæ¹ãããã§ã
ãã®æ§æã䜿çšããå¯èœæ§ãããå Žåã¯2ã€ãããŸãã
// 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>
ãšããŠå®£èšããå¿
èŠããããšæããŸãã åã«èšã£ãããã«ãã¿ãã«åã¯ãåã·ã¹ãã ã®ä»»æã®é·ãã®åã·ãŒã±ã³ã¹ã«äœ¿çšããã®ã«é©åãªããã€ã¹ãšã¯èŠãªãããŠããŸããã 人ã
ãæãè¡šçŸåºŠã®ããã«ãããå¿
èŠã§ãããšç§ã¯ãŸã 確信ããŠããŸããã
ãã£ãšè¡šçŸåããããšæããŸãããåãã©ã¡ãŒã¿ãŒã®äœçœ®ã«ãspreadãæŒç®åããããšãRESTãã©ã¡ãŒã¿ãŒã2åæã€ããšãã§ããªãã®ãšåãããã«ãRESTåŒæ°ã1åã ããã£ããããããã«å¶éãããŸãã ãããã£ãŠã <...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
ããŠãããªãããããã©ã®ããã«èããŠããããããããŸããã ããªããææ¡ããŠããã®ã¯ãå®éã«ã¯ç§ãæã£ãŠãããã®ãšã¯ç°ãªãæ©èœã®ããã§ãã åãã©ã¡ãŒã¿ãŒã®ã·ãŒã±ã³ã¹ããã£ããã£ããããã®æ°ããæ§æãè¿œå ãã代ããã«ãã¿ãã«åã¯ãã§ã«åã®ã·ãŒã±ã³ã¹ãè¡šããŠãããããæ¡æ£å¯èœã«ããå¿ èŠããããŸãã ããããã°ãããŸããŸãªé·ãã®è€æ°ã®ã¿ãã«ãããééçãªæ¹æ³ã§æž¡ãããšãã§ããŸãã
javascriptã§ã¯ã 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ã¯ãJSã®ç²Ÿç¥ã«éåãããã®ã ãšæããŸããéåžžããã®é¢æ°ã«æž¡ãããå®éã®åŒæ°ãããæ£åŒãªåŒæ°ã®å°ãªãé¢æ°ãæž¡ãããã§ãã ç§ãã¡ã¯åã«ãããã䜿çšããŸããã ããšãã°Array.prototype.forEach
æ©èœã«ãªãŒåã¯ã©ãã§ããïŒ ã©ã ãã§ã¯ãããã¯ããããã¯ããã«äžè¬çã§ã
ããã³lodash / fpã
æã2016幎2æ29æ¥ã«ã¯ã13ïŒ45ã«ã¯ãã¢ãããªãŒRessin [email protected]æžããŸããïŒ
@sandersn https://github.com/sandersnãTypeErrorããªã³ã«ãªã£ãŠãããšæããŸã
å€ãã®è°è«ã¯ãJSã®ç²Ÿç¥ã«éåãããã®ã§ãã
éåžžãå®éã®åŒæ°ããã圢åŒçãªåŒæ°ãå°ãªãé¢æ°ãæž¡ããŸãã
ãã®é¢æ°ã«æž¡ãããŸãã ç§ãã¡ã¯åã«ãããã䜿çšããŸããã äŸãã°
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
åºå®çœ²åä»ãã®é¢æ°ãã³ãŒã«ããã¯ãšããŠã©ããã«æž¡ããšã次ã®ããã«èããŸãã 'ç§ã®é¢æ°ã¯_å°ãªããšã_ãããã®åŒæ°ãæåŸ ããŸã'
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))
ããã¯é¢æ°åããã°ã©ãã³ã°ã§ã¯éåžžã«äžè¬çã§ãã ãããŠæåŸãçç¥
è°è«ã¯ããªãäžè¬çã§ãã
æã2016幎2æ29æ¥ã«ã¯ã13æ52åã«ã¯ãã¢ãããªãŒRessin [email protected]æžããŸããïŒ
@isiahmeadowshttps ïŒ//github.com/isiahmeadowsã«ãªãŒåã ãšæããŸã
aruments.lengthã«åºã¥ããšãéåžžã«äžå®å®ã§ãå®è¡æã«ãšã©ãŒãçºçãããããªããŸãã
å®éã®ã«ãªãŒåã¯ãè°è«ã®äœå°ããããŸãããvar plus = x => y => x + y
console.logïŒplusïŒ3ïŒïŒ4ïŒïŒ// 7
console.logïŒplusïŒ3,10ïŒïŒ4,20ïŒïŒ//ãŸã 7â
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190330620
ã
ããšãã°ã map
ãžã®ã³ãŒã«ããã¯ãšããŠãããæž¡ãããå ŽåïŒãªã¹ãã®åŠç
ãªã¹ãã®ïŒãããªãã¯ãããããããã«ã¬ãŒããããšæãã§ãããã
2016幎2æ29æ¥æææ¥ã 13 ïŒ [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))
ããã¯é¢æ°åããã°ã©ãã³ã°ã§ã¯éåžžã«äžè¬çã§ãã ãããŠæåŸãçç¥
è°è«ã¯ããªãäžè¬çã§ããæã2016幎2æ29æ¥ã«ã¯ãååŸ1æ52ã¢ãããªãŒRessin [email protected]
æžããŸããïŒ@isiahmeadowshttps ïŒ//github.com/isiahmeadowsã«ãªãŒåã ãšæããŸã
aruments.lengthã«åºã¥ããšãéåžžã«äžå®å®ã§ãå®è¡æã«ãšã©ãŒãçºçãããããªããŸãã
å®éã®ã«ãªãŒåã¯ãè°è«ã®äœå°ããããŸãããvar plus = x => y => x + y
console.logïŒplusïŒ3ïŒïŒ4ïŒïŒ// 7
console.logïŒplusïŒ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)
æã2016幎2æ29æ¥ã«ã¯ã18æ47åãžã§ã€ãœã³ã»ããªãŒãã³[email protected]ã¯æžããŸããïŒ
[1ã2]ã[æ°å€]ãæºãããã©ããã®è³ªåã¯ã質åããã®ã«æå¹ãªè³ªåã§ãã
ãšèšè«ã ããããããã¯ã¹ãã¬ããå¯èœãªã¿ãã«æ©èœãšäœã®é¢ä¿ãããã®ã§ããããïŒâ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190453352
ã
ãããŠããããå®çšçãªçç±ãããRESTãã©ã¡ãŒã¿ãŒã®ãããªãã®ã奜ãçç±ã§ã
å¯å€ååŒæ°åã
2016幎2æ29æ¥æææ¥ã19ïŒ00 Isiah [email protected]ã¯æ¬¡ã®ããã«æžããŠããŸãã
ã¿ãã«ã®å¯å€ååŒæ°ã¢ããªã±ãŒã·ã§ã³ãäœåãªãã®ãç¡èŠããå¿ èŠããããã©ããã§ã
åŒæ°ãã©ããã ãã®ãªãŒããŒããŒããããé¢æ°ã¯ãç§ã®
æžå¿µã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)
æã2016幎2æ29æ¥ã«ã¯ãåå18æ47ãžã§ã€ãœã³ã»ããªãŒãã³[email protected]
æžããŸããïŒ[1ã2]ã[æ°å€]ãæºãããã©ããã®è³ªåã¯ã質åããã®ã«æå¹ãªè³ªåã§ãã
ãšèšè«ã ããããããã¯ã¹ãã¬ããå¯èœãªã¿ãã«æ©èœãšäœã®é¢ä¿ãããã®ã§ããããïŒâ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190453352
ã
@JsonFreemanããã¯ãåãšé
å/ã¿ãã«ã®spreadæŒç®åã®ããã§ãã ã¹ãã¬ããåæŒç®åããæå®ãããåA
ã B
ãããã³T = [A]
圢åŒã§èš±å¯ãããŠããå Žåã [...T, B]
ã¯[A, B]
ã ïŒæé»çã«ææ¡ãããŸãïŒãã®å Žåãé
å/ã¿ãã«æ¡æ£æŒç®åãšæŽåãããŸããã var a: [A]
ãšvar b: B
äžããããå ŽåãåŒ[...a, b]
ã®åã[A, B]
åã§ãããšèšŒæããããšã¯ã§ããŸããã ã¿ãã«ã®çŸåšã®ã«ãŒã«ã«ããã°ãã¿ã€ã[A, A|B]
ã§ããããšã蚌æãããå¯èœæ§ããããŸãã
ããã¯ããªãã«ãšã£ãŠæå³ããããŸããïŒ ãŸãã¯ãæ¯èŒè¡šãäœæããŠããã®äžäžèŽã匷調ããããšãã§ããŸãã
@Igorbekããªãã®èšã£ãŠããããšãããããŸãã æçµçã«ã¯ãã³ã³ãã€ã©ãŒãåŠçããåã«ã€ããŠå®å
šãªç¥èãæã£ãŠããããå€ã«ã€ããŠã¯å®å
šãªç¥èãæã£ãŠããªããšããäºå®ã«èµ·å ããŸãã ç¹ã«ããã®äŸã§ã¯ãå€a
é·ããäžæã§ãããã¿ã€ã[A]
é·ãã¯æ¢ç¥ã§ãã ãããããã®ç®çã§ã¿ãã«åã䜿çšããããšã«æåã¯äžå¿«ã ã£ãçç±ã®1ã€ã§ããã ãããããããæ·±å»ãªåé¡ãã©ããã¯ããããŸããã
@isiahmeadowsããªããäœãæ±ããŠããã®ãããããŸããã
ã¿ã€ãã»ãŒããœãªã¥ãŒã·ã§ã³ã¯ãä»ã®ãœãªã¥ãŒã·ã§ã³ãšããäžè²«æ§ããããŸãã
åŒæ°ã®æ§æãæš¡å£ããå Žåã®èšèªã
ç§ã®ãã€ã³ãã¯ãRESTãã©ã¡ãŒã¿ãŒãå¹æçã«æ¡æ£ããŠããå Žåã次ã®ããã«ãªããŸãã
æ£ç¢ºã«åŒæ°ã¿ã€ãã§ããããã以äžã§ã¯ãããŸããã ã«ã¬ãŒé¢æ°ã«ã¯ãªã¿ãŒã³ããããŸã
åŒæ°ã®åã«äŸåããåã ãããã£ãŠã1ã€ã®åŒæ°ãé©çšãããããš
ã«ãªãŒåæ©èœãéšåçã«é©çšãããšããŸã£ããéããã®ã«ãªããŸã
ã¿ã€ãã ã¿ãã«ã®ãããªRESTã¿ã€ããåŠçãããšã代ããã«ã©ã³ã¿ã€ã ãšã©ãŒãçºçããŸãã
ããã¯æ±ºããŠè¯ãããšã§ã¯ãããŸããã
ç«ã2016幎3æ1æ¥ã«ã¯ãåå6æ07ãžã§ã€ãœã³ã»ããªãŒãã³[email protected]ã¯æžããŸããïŒ
@Igorbekhttps ïŒ//github.com/Igorbekããªãã®èšã£ãŠããããšãããããŸãã
ããã¯æçµçã«ãã³ã³ãã€ã©ãå®å šãªç¥èãæã£ãŠãããšããäºå®ããçããŸã
ãããæ±ã£ãŠããã¿ã€ãã®ããããå€ã®å®å šãªç¥èã§ã¯ãããŸããã ã®
ç¹ã«ãããªãã®äŸã§ã¯ãå€aã®é·ãã¯äžæã§ããã
ã¿ã€ã[A]ã®é·ãã¯æ¢ç¥ã§ãã ãããç§ãæåã«ããçç±ã®1ã€ã§ãã
ãã®ç®çã§ã¿ãã«åã䜿çšããããšã«äžå¿«æãèŠããŸãã ããããç§ã«ã¯ããããŸãã
ããã¯æ·±å»ãªåé¡ã§ãã@isiahmeadowshttps ïŒ//github.com/isiahmeadowsããªããäœãæ±ããŠããã®ãããããŸã
ã«ã€ããŠã§ãããRESTã¿ã€ãã®ãã©ã¡ãŒã¿ãŒã§åé¡ãããæ確ã«ãªãã®ã¯ãªãã§ããïŒâ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment -190667281
ã
@isiahmeadowsã«ãªãŒååé¡ã®ãµã³ãã«ã³ãŒãã
Restã¿ã€ãã®ãã©ã¡ãŒã¿ãŒïŒç§ããã¹ãŠã§ãïŒã䜿çšãããšããŠããéå°ãªåŒæ°ãèš±å¯ããªãããšãæ瀺çã«æ±ºå®ããå¿ èŠããããšæããŸããããããããããã¹ãã§ãã
@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ãå®éã«æ£ããæ©èœããå Žåã¯ãåºæ¬çã«ãåã®ã·ãŒã±ã³ã¹ãæŽåãããã¡ã«ããºã ãå¿ èŠã§ãã ãã€ã³ãããåŒæ°ã®åãå ã®é¢æ°ã®åŒæ°ãšç §åãããæ®ããæ»ãåã«ãªããçµ±äžã«äŒŒããã®ãå¿ èŠã«ãªããŸãã
ãšã¯ãããææ¡ãŸãã¯è°è«ãããå 容ã§ã¯ãïŒã¿ãã«ã®è¿œå ã®åŒæ°ãèš±å¯ãããŠãããã©ããã«é¢ä¿ãªãïŒãããåŠçã§ãããã®ã¯ãªãããã§ãããäœããèŠéããå¯èœæ§ã¯ãããŸãã
æ倧ã®åé¡ã¯ãåãã©ã¡ãŒã¿ãŒã®åãã¹ãã¬ããåãšç §åããããããçš®ã®ã¿ãã«ãã¿ãŒã³ãããã³ã°ãããã®åé¡ãä¿®æ£ããããã«åãã©ã¡ãŒã¿ãŒïŒLiveScript / CoffeeScriptã®åŒæ°ïŒã§å®è¡ããå¿ èŠãããããšã ãšæããŸãã ããã§ãªããã°ããããäžå¯èœã§ãã ãããŠããããã©ãã»ã©è€éãã«ã€ããŠã¯ããããå®è£ ããããã«é 匵ã£ãŠãã ããã ïŒç¬é¡ïŒ
@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ãšã¯
@JsonFreeman
ãŸããåãå³å¯ã«ãã§ãã¯ããªããšã Function.prototype.bind
ãã®åé¡ãç°¡åã«ä¿®æ£ã§ããã»ã©ã®æ æ°ãå¯èœã«ãªããŸãã ãã®ãããªæ æ°ããããšã次ã®ããã«ããŠãã®åãå®çŸã§ããŸãïŒå宣èšã§è€æ°ã®RESTãã©ã¡ãŒã¿ãŒãåé¡ãªãå Žåãé€ããããããã·ãŒã±ã³ã¹ããããã«ã¿ãã«æ§æãå¿
èŠã«ãªããŸãïŒã
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
ããã¯ãéå³å¯ãªåãã§ãã¯ã®ä»çµã¿ã§ãã èŠãç¬éã§ã¯ãªããå¿ èŠã«å¿ããŠã¿ã€ããæšæž¬ããŸãã ééã£ãã¿ã€ãã倱æããããã«ã2ã€ã®ãã¹ãçµã¿åãããããšãã§ããŸãïŒãããŠãããã¹ãã§ãïŒã äŸïŒ
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
ãå
¥åããããšãããããRESTã¿ã€ããé©çšããããã«ã¿ãã«ã䜿çšããããšã«ã€ããŠã®ç§ã®æèŠãå€ãããŸããã
interface Function {
apply<T, R, ...X>(
this: (this: T, ...args: [...X]) => R,
thisArg: T,
args: [...X]
): R
}
ä»ã®ããã€ãã®ã¡ã¢ïŒ
ts
interface Foo extends Function<void, ...string[]> {}
Function.prototype.bind
ãšãã®å人ã¯ãé¢æ°ã®ãã¹ãŠã®ãªãŒããŒããŒãããã§ãã¯ããå¿
èŠããããŸãã ãã®äœæ¥ãè€æ°ããå Žåã¯ãããããã¹ãŠã®åéåãè¿ãå¿
èŠããããŸãããã ããäŸã®ãããã®åãã©ã¡ãŒã¿ãŒã¯ãå®éã«ã¯ãã€ã³ã眲åã®åãã©ã¡ãŒã¿ãŒã§ã¯ãããŸããã ãããã¯é¢æ°åã«å±ããŸãã ããããããã§ãã2ã€ã®RESTãã©ã¡ãŒã¿ãŒã䜿çšãããã2ã€ã®RESTã¿ã€ãã®ãã©ã¡ãŒã¿ãŒãã¿ãã«ã«åæ£ãããã§ããã°ããããèšè¿°ã§ãããšããèãã§ãã
ãã€ã³ãã®çœ²åãååã«æè»ã«ããã«ã¯ã ...X
ãš...Y
ã®å¢çãåŒã³åºãããšã«æ±ºå®ããå¿
èŠããããŸãã æšæž¬ããå¿
èŠããããŸãã ãã ãã眲åã§...X
ãåç¬ã§äœ¿çšããå Žåã¯åé¡ã«ãªããŸãã ãã®å Žåãå¢çã¯æ±ºå®ãããŠããŸããã äŸãã°ïŒ
interface SomeType<T, R, ...X, ...Y> {
someMethod(someArgs): [...X]; // No way of knowing how long X is
}
ãããŠããªãŒããŒããŒãã¯é¢æ°åã«ãšã£ãŠããªãåé¡ã§ãã ãªãŒããŒããŒãéã§ãã©ã¡ãŒã¿ãŒãæ··åããã³ç §åã§ãããããååŒæ°ã§å ±çšäœåãèŠçŽ ããšã«äœ¿çšããå¿ èŠã¯ãªããšæããŸãã ããã¯ããªããæå³ããããšã§ããïŒ
@JsonFreeman
_TL; DRïŒæ°Žå¹³æ¹åã®æ¹è¡ã«ã¹ãããããŸãã æ°ãããããå®çšçãªã¢ã€ãã¢ããããŸãã_
Function
èªäœã«å±ããŠããããšãç¥ã£ãŠããŸããç§ãèããŠããŸãããåé¡ã®ã¡ãœããã ãã§ãã®çš®ã®ç¶æ³ãå®çŸ©ããæ¹ãããå°ãå®çŸå¯èœãããããŸããã ãŸããããªããã»ã®ãããããã®ãããªæœåšçãªåé¡ãæ€åºããããšã¯ãã¯ããã«ç°¡åãã€è¿ éã«ãªããŸãã
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
}
解決ããã®ãã¯ããã«é£ããæœåšçãªä»ã®åé¡ããããŸãïŒãããŠããªãããã_n _åå²ã§ã¯ãªã2ã«å¶éããå¿ èŠããããšæãã®ã§ããïŒïŒ
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(), {}, []]
)
_ããã§CSçè«ã«æ·±ãå ¥ã蟌ãã§ããå Žåã¯ç³ãèš³ãããŸãã..._
ã¯ããããã¯æ£ããèãã ãšæããŸãã ãããã§ã¯ãããŸãããã Function
ã®ååŒæ°ãç¥ã£ãŠããã®ã§ã bind
ãæ£ããå
¥åããä»ã®æ¹æ³ã¯èããããŸããã 究極ã®ããšã¯ãå¢çãæšæž¬ããªããã°ãªããªããšããããšã§ãã ãŸããçµã¿åãããŠççºããå¯èœæ§ã®ããä»»æã®æ°ã®å¢çã§ã¯ãªãã1ã€ã®å¢çãæšæž¬ããå¿
èŠãããããã«ã2ã€ã®ãã±ããã«å¶éããå¿
èŠãããããšã«åæããŸãã
ç§ãã¡ãèããŠããªãã£ãåé¡ããã£ãšããå¯èœæ§ããããŸãã
@JsonFreemanãã1ã€ã®åé¡ã¯ã curry
ãããªãã®ã§ãã ç§ã¯ãããæ£ããã¿ã€ãã§ãããã®ããŸã æãä»ããŠããŸããã ãããŠãç§ãã§ããããã«ãªããŸã§ã«ã¯ãã°ããæéãããããŸãã ãã®ãããªããã»ã¹ãæãä»ãã«ã¯ãHaskellã®ãããªæ·±å»ãªã¿ã€ãã®ãããã³ã°ãè¡ãå¿
èŠããããŸãã
ããçš®ã®ææ¡ãããã€ãã®Bluebirdé¢æ°ã§ã©ã®ããã«æ©èœããããèããŸãã
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ã®ç§ã®å€§ããªã³ã¡ã³ããåç §ããŠãã ããã ãŸããPromiseã€ã³ã¿ãŒãã§ãŒã¹ãä¿®æ£ããŠãç§ã®ææ¡ã«å°ãè¿ã¥ããŸããã
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
T
ãŸãã¯U
ãRESTãã©ã¡ãŒã¿ãŒã§ããå Žåãéåžžã©ããã«å±éãããŸãã T
ãRESTãã©ã¡ãŒã¿ãŒã§ãããšãããšã [Foo<T1, U>, Foo<T2, U>, /*... Foo<TN, U>*/]
ãŸããå®çšäžã®çç±ããã3ã€ä»¥äžã®RESTãã©ã¡ãŒã¿ãŒã«åŒ·ãå察ããæ®ãã®ãã©ã¡ãŒã¿ãŒãåå²ããå¿ èŠãããå Žåã¯ãã¡ãœããããšã«ã®ã¿åå²ããå¿ èŠãããããšã«æ³šæããŠãã ããã ãã®ãããªãã®ïŒ
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>
]
ãã®ãããŸããã¯æ··ä¹±ãåŒãèµ·ãããŸãããïŒ ããããã1ã€ã®æ¬¡å ã«å¶éããã®ãè³¢æã§ãããã
åå²æ§æã®ä»£æ¿æ¡ïŒ
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
ç§ã¯2çªç®ãæåŸ ããŸãã ãããŠããããäžè²«ããŠããã§ããéãã人ã ã¯ããã«ããã«æ £ããŠããŸãã®ã§ããããããŸãã«ãå€ãã®æ··ä¹±ãåŒãèµ·ããããšã¯ãªããšæããŸãã ããã¯ãŸãã圌ããäœãããŠããã®ããç¥ã£ãŠãã人ã ããŸãã¯ããããå¿ èŠæ§ãçãã¹ã人ã ã«ãã£ãŠã®ã¿å®éã«ééããã§ãããçãããšããžã±ãŒã¹ã§ãã
ç§ã¯ãŸããããªããæåã®éšåãæ¡åŒµãã次ã«æåã®éšåã®åéšåã«ã€ããŠ2çªç®ãæ¡åŒµããŠãããšãã«ãããèŠãŠããŸãã ãã®æ¬äŒŒã³ãŒãã®ããã«ïŒ
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
ã®ã¿ã€ããå€æŽããããšãã§ããŸãã
ãã®ã¢ãããŒãã®åé¡ã®1ã€ã¯ã this
ãã€ã³ãã§ããã®ã¯1åã ãã§ãããšããããšã§ããããšãã°ã次ã®ããã«ãªããŸãã
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ã«åæããŸãã å°ãªããšããã®æ®µéã§ã¯ãå¯å€ååŒæ°åãã©ã¡ãŒã¿ãŒã®ããåºæ¬çãªåé¡ã解決ããããšããŠããããšãèãããšãåã®ã·ãŒã±ã³ã¹ã®ãããã³ã°ã¯åªå äºé ã®ããã«ã¯èŠããŸããã
ç§ã¯ãããçŠæ¢ããããšã«ããã»ã©åé¡ã¯ãããŸããïŒå°ãªããšãæåã¯ïŒããªããªãããã®æ¯ãèãã¯ããªãäžçŸ©çã§ããã2人ã®ç°ãªã人ã
ã2ã€ã®éåžžã«ç°ãªãããšãæåŸ
ãããããããªãããã§ãã TypeScriptã¯æåã«é«æ¬¡ã®åã¢ãã«ãæã£ãŠããå¿
èŠãããã®ã§ïŒããæå³ã§map
ãåã«pingãå®è¡ããïŒãå°ãªããšãä»ã®ãšãã@Igorbekã«åæããŸãã ãããŠãããé«æ¬¡ã®ã¿ã€ãã¯ãããªãããã ãã«ãã§çããããšãã§ãããã®ã§ã¯ãããŸããã
ã ããééããªãïŒ+1ïŒãããçŠæ¢ããããã«ãããããããªãé·ãéã TypeScriptã¯æ©èœçã§ã¿ã€ãã»ãŒããªåã·ã¹ãã ã䜿çšããŠããªããããæã£ãŠããã®ã¯è¯ãããšã§ãããå®è£ ã¯éåžžã«è€éã§ãå®å šã«ããã¯ããå¿ èŠããããŸãã
å°ãé ããŠæ¥ãŸããã @ Igorbekã«ãåæããŸãã ïŒ1336ã§è¡ã£ãç§ã®ã³ã¡ã³ããç¹°ãè¿ããæ確ãªãpackãããã³ãunpackãæŒç®åãæã€C ++ãã©ã¡ãŒã¿ãŒãããã³ã°ããã¢ã€ãã¢ãåããŠããŸãã
ã¿ã€ããã¿ãã«ã«ããã¯ããããšã¯ãTypescriptã®spreadæŒç®åã®äœ¿çšæ³ãšäžèŽããŠããããã§ãã
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...]
ã®æšè«ãã¯ããã«ç°¡åã«ãªããŸãã
C ++ã¯ããã¯ã«spreadæŒç®åã䜿çšããã¢ã³ããã¯ã«çç¥èšå·ã䜿çšããŸãããäž¡æ¹ã«spreadã䜿çšãããšãTypescriptãšã®äžè²«æ§ãé«ãŸããŸãã
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ãã®ååã¯æåã®ã¢ã€ãã¢ã§ããããããã«ã¬ã¹ããã©ã¡ãŒã¿ãŒïŒäžéšã®APIã«ã¯ãããŸãïŒã®å Žåã«ã€ããŠã¯èª¬æããŠããŸããã
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]);
}
ç§ã¯è¿œãã€ããŠããŠãã¿ãã«åãå³å¯ãªé·ãã§ãããšçŽ æŽã«æ³å®ããŠããããšã«æ°ã¥ããŸããã ã©ã®imoãæãçŽæçã§ãã ã§ã¯ãå³å¯ãªé·ãã®ã¿ãã«åïŒïŒ6229ïŒãååŸãããšä»®å®ãããšãåé¡ã¯äœã§ããïŒ
@isiahmeadowsäžèšã®ããã«ã¬ã¹ããã©ã¡ãŒã¿ãŒã®å Žåã®äŸã§ã¯ãå³å¯ãªé·ãã®ã¿ãã«ã䜿çšããããšã§è§£æ±ºãããŸãããïŒ arr = [...other, 123]
å±éããã¹ãã¬ãããšåãããã«...rest: [...T, Baz]
èªãã§ããŸãã ããã¯ããªãã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
ããšåéããŸãã¯ããäžè¬çã«ã¯éšåé©çšã䜿çšãããã®ã ãŸããåé¢ããRESTãã©ã¡ãŒã¿ãŒãéžæã§ããå¿
èŠããããŸããããã¯ãå®éã«ã¯ã¡ãœããããšã«ã®ã¿å®è¡ã§ããŸãã
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
ããã«ãRESTãã©ã¡ãŒã¿ãŒã2ã€ã«åå²ããæ©èœãå¿
èŠãªã ãã§ãªããã¡ãœããããšã«éåžžã«ããªããã£ããªãã¿ãŒã³ãããã³ã°ãå®è¡ããæ©èœãå¿
èŠã§ãã
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
ãè¿œå ããŠããã¥ãŒãªã³ã°å®å
šã«ãªããšã¯æããŸããããè¿ãã§ãããã ããã劚ããäž»ãªãã®ã¯ãç¹å®ã®åã®å°éåéã«äžèŽããèœåã ãšæããŸãïŒC ++ãScalaãHaskellããã¥ãŒãªã³ã°å®å
šåã·ã¹ãã ãåãã3ã€ã®èšèªã¯ãã¹ãŠæã£ãŠããŸãïŒã
@sandersnäžèšã®äŸã¯è¡šç€ºãããŸããã§ããããå¯å€ååŒæ°ãã©ã¡ãŒã¿ãŒã®å¶çŽã«ã€ããŠè³ªåã§ããŸããïŒ
次ã®äŸãèããŠã¿ãŸãããã
interface HasKey<T> {
Key(): T;
}
class Row<...T extends HasKey<X>, X> {
// ...
}
_ã¡ãªã¿ã«ã X
ããªã¹ãããå¿
èŠããããšããèŠä»¶ãåé€ããå¯èœæ§ã«ã€ããŠã¯ã httpsïŒ //github.com/Microsoft/TypeScript/issues/7848ãåç
§ããŠ
ããã§ãå¶çŽã次ã®ãããã§ãããã«ã€ããŠããããŸãããçããå¯èœæ§ããããŸãã
(...T) extends HasKey<X>
ãŸãã¯...(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>
以äžã§ïŒãšT F-æçïŒïŒ
function processItems<...T extends Item<T>>(...args: [...T]): void {
for (const arg of args) { // Here
process(arg);
}
}
ããã¯ãã¿ã€ããããŒã«ã«ã§è§£æ±ºã§ããããã«ããããã§ãã äºåã«åãããããªãå Žåã¯ãé¢æ°ãåŒã³åºããã³ã«é¢æ°å
ã§åãèšç®ããå¿
èŠããªããããã³ã³ãã€ã«ã倧å¹
ã«é«éåãããŸãã åäžã®åŒæ°ã®åã ããå¿
èŠãªå Žåã¯ã typeof arg
ååã§ãããããããçããªãããšã«æ³šæããŠãã ããã
ç³ãèš³ãããŸããããå
ã®äŸã§ã¯ãã¿ã€ãã¯T
å¿
èŠããããŸãã å®éã2çªç®ã®äŸã§ã¯ãTã§ããå¿
èŠããããšæããŸãã
ç§ã¯2çªç®ã«Item<any>
ãæå³ããŸãã...ããããªããã
Tã§ããå¿
èŠããããšèšã£ããšããTã¯ã¿ã€ãã§ãããšæ³å®ããŠããŸãããããã®æ©èœã®èŠç¹ã¯ãTãã¿ã€ãã§ã¯ãªããšããããšã ãšæããŸãïŒç§ã¯æããŸãïŒã ããã§ãããããªãã®äŸã§ã¯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ã¯å¯èœã§ãããå¯èœæ§ã¯äœããšæããŸãã
ãªããžã§ã¯ãã®REST / SpreadïŒïŒ2103ïŒãé©åã«ãµããŒãããããšãçŽæããå Žåãå¯å€ååŒæ°ã®çš®é¡ã¯ãåãæ¡æ£ããŠäžåºŠã«ãã¹ãŠãå®è¡ããããšãæ£åœåããã®ã«ååè¿ãå¯èœæ§ããããŸãã ïŒã¹ãã¬ããã¿ã€ãã¯ã { ...T, x: number, ...U, y: string, ...V }
ããã«èŠãããªããžã§ã¯ãã¿ã€ãã®ããªã¢ã³ãã§ããïŒ
n overloads
åé¿çã¯ãã¯ã©ã¹ãã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯æ©èœããªãããšã«æ³šæããŠãã ãããããã¯ããã®æ©èœã«ç¹ã«é¢å¿ããããŸãã
@sandersn ã_n_overloadsãã®ãã«ãªã¯ãšã¹ãã¯ã this
å
¥åã䜿çšããŠãé¢æ°ã®bind
ã apply
ãããã³call
ã«æåŸ
ãããŸããïŒ ããã¯å€ãã®äººã«ãšã£ãŠèš±å®¹ã§ããäžæçãªåŠ¥åæ¡ã§ãããäžéšã®ãããžã§ã¯ãã®éçšã§ããªãã®æ°ã®ãã°ãèŠã€ããå¯èœæ§ããããšæããŸãã
@isiahmeadows
å¿ ãããTã§ããå¿ èŠã¯ãªããšæãã®ã¯ãTãäœã§ãããããããªãããã§ãã
Tã¯å¯å€ååŒæ°åã®ã¿ãã«åã§ãããšããåæããã£ãããã«ç§ã«ã¯æããŸããã å
ã®äŸã§ã¯ã arg
åã¯ã¿ãã«èŠçŽ ã®åãšåãã«ãªããŸãïŒ @JsonFreemanããèŠçŽ ã®å
±çšäœåããšè¿°ã¹ãããã«ïŒïŒä»ã®ãšãããtypescriptãã¿ãã«ãæ®ããšããŠäœ¿çšããããšããµããŒãããŠãããšæ³åããŠãã ããã¿ã€ãïŒïŒ5331ïŒã
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ã€ã®æ©èœã2.1ã«ãªã£ãããšãŠãå¬ããã§ãã ç§ã¯å°ãªããšã1ã€ã®ã©ã€ãã©ãªïŒRxJSïŒãç¥ã£ãŠããŸãããããã®æ©èœã«ãã£ãŠã³ãŒãããŒã¹èªäœãæ¹åãããã ãã§ãªããã³ãŒãã®æ¶è²»ãå€§å¹ ã«è»œæžããããã°ãçºçãããããªããŸãïŒAngular 2ã䜿ãå§ãã3人ã«1人ã¯ãã€ã³ããŒãããªãããã«åãŸããŸããç£èŠå¯èœãªãããã¿ã€ãã«ããããé©çšãããŠãããªãã¬ãŒã¿ãŒã®å ŽåïŒã ããã¯ãä¿å®å¯èœãªé¢æ°åã³ãŒããæžããããšèããŠãã人ã ã«ãšã£ãŠãæ¬åœã«ç»æçãªæ©èœã«ãªãã§ãããã
ããã䜿çšããŠã _.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 };
}
ã6ããããæ§æã¯ãã¿ãã«ã®çš®é¡ã®å€æ°ã®ãªããžã§ã¯ãã¹ãã¬ããã§ããããšã«æ³šæããŠãã ãããããã«ã€ããŠã¯ãäžèšã§ã¯å®éã«ã¯èª¬æããŠããŸããã
@sandersn
ã§ã¯Object.assign
ããã®ç®æšãå€ç°ããããããç¹ã«ãããã¯ïŒããªãã¯ããã®ããã®åºæºç¹ãæã£ãŠããå¿
èŠãããã ããïŒããã®æ¹æ³ãå
¥åããæè¡çã«ïŒããŸãã«ãinferrably匱ãå°ãã¯ãããïŒã®ãµãã»ããããã£ããã£ããããšãã§ããŸãïŒ
assign<T>(target: T, ...sources: Partial<T>[]): T;
ããã«é¢ããäžå ·åã¯ãã¿ãŒã²ãããå€æŽãããã®æ§é ã¿ã€ããæå®ã®äœçœ®ã«å€æŽããããšã§ãã
@isiahmeadowsã®å Žåãæšè«ã«ããT
ãsources
ã¢ã«ãŠã³ãã£ã³ã°ã¿ã€ããªãã§target
ã¿ã€ãã«ä¿®æ£ãããŸãã éå¯å€ããŒãžã§ã³ã§ä»ããè©Šãããšãã§ããŸãïŒ
declare function _assign<T>(target: T, source: Partial<T>): T;
_assign({}, { a: 10 }); // T is {}
ãã§ã«è¿°ã¹ãããã«ã assign
ã¯_ã¹ãã¬ããã¿ã€ã_ïŒ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ãšããã§ãå¯å€ååŒæ°ã®çš®é¡ããã€äžéžãããã«ã€ããŠã®æŽæ°ã¯ãããŸããïŒ 2.2ã§ãããèŠããã£ã³ã¹ã¯ãããŸããïŒ
ãããŠãæ§æã«é¢ããŠãããªãã¯ãŸã æ§æã«é¢ãããã£ãŒãããã¯ãåãå
¥ããŸããããããšãããªãã¯ãã¹ãŠããã«åæããŸããïŒ
æ§æãšäœã¬ãã«ã®ã»ãã³ãã£ã¯ã¹ã«ã¯ããŸã æ確ãªã³ã³ã»ã³ãµã¹ããããŸããã
ç«ã2016幎12æ13æ¥ã«ã¯ã13æ26åã€ãŽãŒã«Oleinikovã®[email protected]ã¯æžããŸããïŒ
@sandersn https://github.com/sandersnãšããã§ããã€æŽæ°ãããŸãã
å¯å€ååŒæ°ã®çš®é¡ãäžéžããäºå®ã§ããïŒ 2.2ã§ãããèŠããã£ã³ã¹ã¯ãããŸããïŒ
ãããŠãæ§æã«é¢ããŠãããªãã¯ãŸã æ§æã«é¢ãããã£ãŒãããã¯ãåãå ¥ããŸããïŒ
ããªãã¯ãã¹ãŠããã«åæããŸããïŒâ
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/5453#issuecomment-266819647 ã
ãŸãã¯ã¹ã¬ããããã¥ãŒãããŸã
https://github.com/notifications/unsubscribe-auth/AERrBIa5fE8PSk-33w3ToFqHD9MCFoRWks5rHuM5gaJpZM4GYYfH
ã
ãã®åé¡ã®ç¶æ³ã«ã€ããŠäœãèãã¯ãããŸããïŒ
ããã§ãããªããèããŠãããªãã·ã§ã³ã¯äœã§ããïŒ ããã¯ããŒã ã®è°é¡ã§ããïŒ ããã¯ç§ãç¹°ãè¿ãééããåã·ã¹ãã ã®å¯äžã®åŒ±ç¹ã§ãã ç§ã«ã¯2ã€ã®ãŠãŒã¹ã±ãŒã¹ããããŸãã åçŽã§è€éã§ãããããäžè¬çãªãã®ã§ãã
ç°¡åãªã®ã¯ãã¿ãã«åã«ãã£ãŠã®ã¿ãµãã¿ã€ãåã§ãã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)
ãããç§ã¯æšæ¥TypeScriptã䜿ãå§ããã°ããã§ãé¢æ°ãã©ããããããã«äœ¿çšããŠããåäžã®ãã³ã¬ãŒã¿ã®ããã«ãé¢æ°ãèªåçã«å ¥åããããšã¯ãã§ã«äžå¯èœã«ãªã£ãŠããŸãïŒãã¡ããæåã§å ¥åããããšãã§ããŸãïŒïŒãããæåã®ããšã§ãïŒç§ã¯ããå§ããŠã¿ãŸããïŒïŒïŒ
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[]
ãã ãã _flatMap
ãããã©ã¡ãŒã¿ãŒã®åãæœåºããŠãè£
食ãããé¢æ°ã®åå®çŸ©å
ã§äœ¿çšããããšãã§ããªãããã types
ãããŒã¿ãã«ã«è¿œå ããæ¹æ³ã¯ãããŸããããã®ææ¡ã§æ³åã§ããŸãã次ã®ããã«èšè¿°ããŸãã
// 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
}
TypeScriptã§ã®æåã®çµéšã瀺ããå¯å€ååŒæ°ãžã§ããªãã¯ãéèŠã§ããçç±ã®å¥ã®ã±ãŒã¹ã瀺ããŠããã®ã§ããããå ±æãããã£ãã ãã§ãã
@sandersn ïŒ
ããã¯ãŸãšããªåé¿çãæã£ãŠããŸã-nãªãŒããŒããŒã
æè¡çã«ã¯æ£ãããããŸããããããã¯ããã§ã®çŸå®ãå®å
šã«ã¯åæ ããŠããªããšæããŸãã ãããæè¡çã«ã¯ããããªããŠãããªãŒããŒããŒãããã®ã¹ã¬ããã§èšåãããŠããé¢æ°ãå
¥åããã®ãé²ãããšã¯ã§ããŸããã§ããã ããã§ãããã®å°ããªäžäŸ¿ã¯ããããŸã§ã®ãšããããã®ãããªéè² è·ããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ãlib.d.ts
ãªã£ãŠããªãããšãæå³ããŠããŸãã
å®éããã®ã¹ã¬ããã®å€ãã¯ã ......
ãã ...*X
ã [...T = ...A, ...B, ...C]
ãªã©ãå
ã
ãã®ææ¡ã®äžéšã§ã¯ãªãã£ãããã«å€ãã®æ§æãææ¡ããããã«ãããããã®é¢æ°ã«åãçµãããšã«å¿
æ»ã«æããŠããŸãã [...PromiseLike<T>]
ã <[...X, ...Y] = [...A]>
ãããã³<PromiseLike<T*>>
ã
ããã¯ãç§ãã¡å šå¡ãããã§åé¡ã«åãçµãã§ããããšã瀺ããŠãããšæããŸãããã®ãããªãã匷åãªæ§æãå¿ èŠã§ãããšããäžè¬çãªæèŠãå ±æããŠãããããã§éžæããæ¹æ³ãåé¡ã®è§£æ±ºã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ãµã€ãããŒãïŒçšRAMDAã®R.path
ãæã
ã¯ãŸã ïŒãŸã é£ããé åãççºããã ããæ¹æ³ïŒã¿ãã«ã®ãµããŒããéããéè² è·ã®åã£ãœãã©ã€ã³ã®å
¥åãçæããã¡ããã©çµäºããªãããã«ãå®éã®ãããžã§ã¯ãã§ã³ã³ãã€ã«ãåŒãèµ·ãããŸããããã ããã«äžèŠå®è¡å¯èœãªä»£æ¿æ段ãšããŠæè¿çºèŠãããå埩ïŒïŒ12290ïŒã
ã¡ãªã¿ã«ã @ Artazorãš@Igorbekãææ¡ããææ¡ã«ã€ããŠã¯ãŸã ã³ã¡ã³ãããŠããŸããã ããã«ã€ããŠã©ãæããŸãããïŒ
ããã§ãã®ãããªåºæ¬çãªå®è£ ïŒããã³ïŒ6606ïŒã«ã€ããŠè°è«ãããã®ã§ãããç§ãã¡ã¯ã»ãŒäœã§ãã§ããŸãã ããã説æããããã«ãããã§ããã€ãã®è§£æ±ºçãæäŸããŸãããããã«è³ªåãããããšãã§ããŸãã
ãŸãã ...
æŒç®åãå®è£
v ...
for | å®çŸ©ïŒãã£ããã£ïŒ| 䜿çšïŒæ¡æ£ïŒ
-|-|-
é¢æ°| 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>
ïŒãã£ããã£[1, 2, 3
]ã«T
ïŒã 楜ããã§ãããã©ã®ãŠãŒã¹ã±ãŒã¹ã§ãããå¿
èŠãããããŸããã | å®çŸ©type Bar<A,B,C>
è¡ãBar<...[1,2,3]>
ïŒ A
= 1
ãªã©ïŒã åäžããããå¿
èŠãšãããŠãŒã¹ã±ãŒã¹ãç¥ããªãã
çµåïŒããŒãã¹ïŒ| ïŒ | type Union = "a" | "b"; type MyTuple = ...Union; // ["a", "b"]
ïŒé åºã¯ä¿¡é Œã§ããŸããããã¿ãã«ãä»ãããŠããªã³/ãªããžã§ã¯ãã®å埩ãå¯èœã§ãããšã«ãããããã§ã¯ç¯å²å€ã§ããïŒ
ãããã£ãŠãããã«é¢é£ããã¿ã€ãã¬ãã«ã®...
ã€ã³ã¹ã¿ã³ã¹ã¯2ã€ã ãã§ãã å
·äœçã«ã¯ãããã§äœ¿çšããã2ã€ïŒ
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);
}
@danvk ïŒ
_.extend
@sandersn ïŒ
Object.assign
ãããã¯äž¡æ¹ãšããRamdaã®mergeAll
ã®å¯å€ååŒæ°ããŒãžã§ã³ã§ãã 6ã€ã®ãããã¯å¿
èŠãããŸããïŒ
@isiahmeadows ïŒ
ãã®åé¡ã®ç¶æ³ã«ã€ããŠäœãèãã¯ãããŸããïŒ
æ§æãšäœã¬ãã«ã®ã»ãã³ãã£ã¯ã¹ã«ã¯ããŸã æ確ãªã³ã³ã»ã³ãµã¹ããããŸããã
ç§ãæ£ããç解ããŠããã°ãããªãã¯äž»ã«ãä»ã®ããã€ããæäŸããã¢ãããŒãããããªããèšåããcurry
ãbind
ãªã©ã®ããé£ããã¿ã€ãã³ã°ãžã®åãçµã¿ãèæ
®ã«å
¥ãããã©ãããå¿é
ããŠããŸããã 圌ãã®ææ¡ã«ç¶ããŠãããããã®ç¹å®ã®ãã®ã«ã€ããŠã®ç§ã®èŠè§£ã§ãã
æŠç¥ã¯å°ã䌌ãŠãããé¢æ°é©çšãžã®åŒæ°ã®åãã§ãã¯ã延æããããšã«ãã£ãŠãé¢æ°åããã¿ãã«åã«params iãjã®åèŠä»¶ãæœåºãããšããã®ã¯é£ãããšããäºå®ãã ãŸããŸãã
// 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*>>
ã«ã¯ããŸãå察ããŠããŸããã ããããIMOã¯ããã£ãã®...
ã§ããä»ã®ãšããå®éã®åé¡ã«å¯ŸåŠããã®ã«åœ¹ç«ã¡ãŸããç§ã¯ããã解決ãããããšãæãã§ããŸãã
ç·šéïŒ bind
ã®åŒæ°ã®å¶çŽã解決ããŸããã
ããããã°ããã質åã§ãã ããã¯ãã«ã¬ãŒé¢æ°ãæ£ããå
¥åã§ããããšã¯éåžžã«ææã«èŠããŸãã
ããããå®éã®ãããžã§ã¯ãã®äžã«ã¯ãé¢æ°åããã°ã©ãã³ã°æåã®ã³ãŒããå
¥åããã®ã«å€ãã®æéãè²»ãããããªããã®ããããŸãã
ãããã£ãŠã --strict
ã¯_tsconfig.json_ã§ããã©ã«ãã§æå¹ã«ãªã£ãŠããã®ã§ãã³ãŒãã®äžéšã®åãã§ãã¯ãç¡å¹ã«ããæ¹æ³ããããã©ããçåã«æã£ãŠããŸãïŒæ æ°ãŸãã¯æéã®äžè¶³ã®ããïŒã
ããããç§ãèšã£ãããã«ãããã¯ããããæããªè³ªåã§ã... ^ _ ^
@ yahiko00ã¯ã¡ãã£ãšãªããããã¯ã§ããã tsconfig
exclude
ã»ã¯ã·ã§ã³ããŸãã¯ç°ãªããããžã§ã¯ãã¬ãã«ã®ç°ãªãtsconfig
ãŸãã
ãŸããå¥ã®ææ¡ãããããšæããŸãã &
ãš|
ãã次ã®æ§æã®åäžã®ã¿ãã«åŒæ°ã§æ©èœããããã«ããããšãã§ããŸããã
<...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 ïŒ
åŸã§åç §ã§ããããã«ãããã«æ®ããŠãããŸãã
ç§ã¯ããã«åããŠå®éšããŠããããã€ãã®PRãéããŸããïŒ
const c = 'a' + 'b';
åé¡ã解決ã§ããŸããïŒ c
æšè«ã¿ã€ãã¯'ab'
ã§ã¯ãªãstring
StackOverflowã«é¢é£ãã質åïŒ TypeScriptã®æ瀺çãªæåŸã®é¢æ°ãã©ã¡ãŒã¿ãŒ
@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æ£ããæ¹æ³ã¯ããã®ææ¡ãå®è£
ããããŸã§ãé¢æ°ã«å€ãã®ãªãŒããŒããŒããäœæããããšã§ãã
ããšãã°ãpromise.allã¿ã€ããåç
§ããŠãã ãã
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 {
å®è¡æã®RESTãã©ã¡ãŒã¿ãŒã¯é åã§ãããçŸåšTSã§ãããè¡ãããšãã§ããŸãã
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]
ããã«ã2ã€ã®ã¿ãã«ã¿ã€ããé£çµããããšã«ã¯æå³ããããŸãã
@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,
èªããšãã«æåã«é ã«æµ®ãã¶ã®ã¯ããããæ¡æ£æŒç®åã§ãããšããããšã§ãããå®éã«ã¯æ¡æ£ã¯ãŸã£ããè¡ããŸããã
@Griffork ãããªãã®äŸã§ã¯ã T
ã¯ãŸã [string, int]
ãŸãã
ãããã @ felixfbeckerããTSã³ã³ãã€ã©ãTã®ã¿ãã«åãæšæž¬ã§ããããã«ãã代ããã«ããå°ãªããšãç§ãç解ããŠããæ¹æ³ã§æå³ããããšã§ãã
ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãåãã¿ã€ããšããŠæ±ãããããã«åŒ·å¶ããããå ·äœçãªã¿ã€ããã§ãã¯ãè¡ãããšã¯ã§ããŸããã ããšãã°ãäžèšã®ç§ã®äŸã§ã¯ããã¹ãŠã®æ»ãå€ã¯anyåã«ãªããŸãã
@Grifforkããããç§ã®èãã§ã¯ã args
é
åã®ã¿ãã«åãæšæž¬ããã¿ãã«å
ã®äœçœ®ã«ãã£ãŠåãã©ã¡ãŒã¿ãŒã«ç¬èªã®åãäžããŸãã ...args: T[]
ã¯ãããããã¹ãŠãåãåT
ã«åŒ·å¶ããŸããã ...args: T
ïŒçŸåšã¯ã³ã³ãã€ã«ãšã©ãŒã§ãïŒã¯T
ã¿ãã«åãæšæž¬ããŸãã
apply <... 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
ãªã©ã®1ã€ã®ã¿ã€ãïŒã«å²ãåœãŠå¯èœã§ãããšæããŸãã
äžèšã®ææ¡ã®ãã€ã³ãã¯ããžã§ããªãã¯ã¹ãä»»æã®æ°ã®åãè¡šçŸã§ããããã«ããããšãæé»çã«åé¿ããããšã§ããã
@felixfbecker
ç·šéïŒ
ãããããããŸããã ããã§ãããããçŽæçã ãšã¯æããªãã§ãã ããã
Tã¯äœãã®é åïŒããšãã°string []ïŒã§ãããšæããŸãã
ã¿ãã«ã¯ãäœãã®é
åãã§ãããåºå®é·ã§åèŠçŽ ã®ç¹å®ã®åãæã€åãªãé
åã§ããããšãã°ã [string, number]
ïŒvs (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ä»æ§ã§ã¯ãå埩å¯èœã§ãªããã°ãªããªãããšãæå³ããŸãïŒãTypeScriptã§extends
ããŠãããè¡šçŸããæ¹æ³ããã§ã«ãããŸãã
function foo<T extends Iterable<any>>(spreadable: T): [...T, string] {
return [...spreadable, 'abc']
}
const bar = foo([1, true])
// bar is [number, boolean, string]
ãã¡ãããRESTãã©ã¡ãŒã¿ãŒã®å Žåãããã¯Iterableã ãã§ãªããé åã§ããããšãç¥ãããŠããŸãã
ããã¯ãç§ãã¡ãèšã£ãŠããããšã¯ãã§ã«ææ¡ãããŠããŸãïŒ https ïŒ
ããããæ®ãã¯1ã€ã®åº§åžã§æ¶è²»ããã«ã¯é·ãããŸãã ð·
ã¿ãã«é£çµãçéžããŠããå Žåã¯ãæäŒçªå·ãå®è£ ã§ããŸãïŒ ãã£ããŒïŒ
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]
ã䜿çšããããã«ããŠã¿ãŸãããã
ã¿ã€ãã¬ãã«ã®åŒæ°ã®äœçœ®ã¯ãã¿ã€ãã¬ãã«ã®ã¿ãã«ã®å Žåãã¿ã€ããéæ§é åããŸããïŒ ãããå¿
èŠã«ãªããŸã
ã¿ãã«ã䜿çšããŠRESTãã©ã¡ãŒã¿ãŒãå
¥åã§ããããã«ããŸããããã«ãããåŒã³åºããµã€ãã§æ¬¡ã®ããã«ãªããŸãã
TypeScriptã®å ŽåïŒ
const first = (a: number, b: string) => âŠ;
const second = (...ab: [number, string]) => âŠ;
first(12, "hello"); // ok
second(12, "hello"); // also ok
INB4ããããããã¯ã¿ã€ãæåã®æŸåºã§ããâãããã ããã¯äœãå€æŽããã first
ãŸã 2ã€ãããŸã
åå¥ã®åŒæ°ãçºè¡ãããŠãã second
ã¯ãŸã 1ã€ã®RESTåŒæ°ããããŸãã å€æŽãããã®ã¯
åŒã³åºããµã€ãã§ãTypeScriptã¯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ïŒç§ã¯æãïŒïŒä»¥éã®ã¿ãã«ã®å²ãåœãŠå¯èœæ§ãã©ã®ããã«ãããããšããããšã§ãã
ã¿ãã«ã®é·ããèæ
®ã«å
¥ããâ_ä»»æã®ã¿ã€ãã¬ãã«ã®ã¿ãã«_ã®æŠå¿µãè¡šçŸããŸãã ãããå€åäœãã®ãããª
[...]
ã¯æ©èœããŸããïŒ åŒ·ãæèŠã¯ãããŸããããã³ã³ã»ããã«ååãä»ããŠããã ããã°ãšæããŸãã
// bikeshed me
type OnlyTuplesWelcome<ArgumentT extends [...]> = ArgumentT;
ãã®å Žåãäžèšã®[...ArgsT]
æ§æã¯ãåºæ¬çã«ArgsT extends [...]
çç¥åœ¢ã«ãªããŸãã
ã¿ã€ãã¬ãã«ã®ãã¹ãã©ã¯ãã£ãªã³ã°ã䜿çšãããšããããšã¯ãã¿ã€ããã¿ã€ãã¬ãã«ã®ã¿ãã«ã«ãªããšããå¶çŽãæå³ããŸãã
èãïŒ
@jaen ïŒ
(...ab: [number, string]) => âŠ
ãããããã¯ïŒ4130ã®ããã«èŠããŸãã ïŒ18004ã§äœããè©ŠããŸããããç§ã®ã¢ãããŒãã¯å°ãããããŒã§ããïŒåæããŒãïŒã
ã¿ãã«ãè¡šçŸããéã«ã誰ããany[] & { 0: any }
ã䜿çšããŠããã®ãèŠãããšããããŸããããã¯ã空ã®ã¿ãã«ã¿ã€ãfwiwãŸã§æ©èœãããšæããŸãã ç§ã¯å人çã«ã¯ããŸãæ°ã«ããŸããã§ããããã»ãšãã©ã¯any[]
ã
RxJSã¯ããããã¡ãã¡ã§å¿
èŠãšããŠããŸãã æãéèŠãªã®ã¯Observable.prototype.pipe
ãçŸåšå€ãã®ãªãŒããŒããŒãããããŸãããåžžã«ããã1ã€ã®ã¬ãã«ããè¿œå ããããã«æ±ããããŸãã
2çªç®ã®@benleshã§ã¯ãRXJSãåºç¯å²ã«äœ¿çšããŠããããã€ãé¢æ°ã«ãããå¿ èŠã§ãã
ç§ã¯ppipeã®äœè ã§ããããã¯ãRXJSã®ãã€ãé¢æ°ãšåæ§ã«ããããå¿ èŠãšããŸãã ããã«æš¡æ§ãèŠãããšæããŸã^^
ç§ã¯runtypesã®äœæè ã§åéåãšå ±ééšåãè¡šçŸããããã«åå®ã«å¿ èŠãšãããŠããŸãã å¯äžã®ïŒäžå®å šãªïŒåé¿çã¯ã巚倧ãªéè² è·ã§ãã
https://github.com/pelotom/runtypes/blob/master/src/types/union.ts
ð€¢
ã©ã ãã®çš®é¡ãæžãçŽããŸããããããpipe
ãã¬ã³ãºãã«ãªãŒåãªã©ã«å¿
èŠã§ãã
ã«ãªãŒåã«ãã£ãŠéè² è·ãçŽæ¥ç¶æããããšã管çã§ããªããªã£ããããcodegenãå¿
èŠã§ããã path
ã¿ã€ãã¯1000è¡ãè¶
ããŠããŸãããããã®æç¹ã§ãªãŒããŒããŒãã¿ã€ãã®ããã©ãŒãã³ã¹ãåé¡ã«ãªã£ãŠããããšãããããŸããã
RESTåŒæ°ã®æšæž¬ãšé©çšã«é¢ããåé¡ã¯è§£æ±ºãããŸãããïŒ
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)
}
äžã«Tã®ã¿ã€ãã®å Žåã¯apply(example, ['0', 1, 2, 3])
ãšæšå¯ããã[string, number[]]
ãé©çšããåŒã³åºãããšã©ãŒãçºçãããã§ãããã
ã€ãŸããTã®ã¿ã€ãã¯æ¬åœã«
type T = [string, ...number[]]
ãŸã
type T =
{0: string} &
{[key: Exclude<number, 0>]: number} &
Methods
確ãã«å¥åŠãªç£ã§ããã ({0: string} & Array<number>)[0]
ãã©ã®ããã«ãªãããèãããš
çŸåšstring
解決ãããŠããŸã[1]ããŸãå€æŽããã«ãšã³ã³ãŒãã§ããããã§ã
åã·ã¹ãã ã«ã
[1]ããã¯ãã°ã§ãããæ¬åœã«string | number
ãŸããïŒ
ãã®åé¡ã®36人ã®åå è ã«è¿·æããããŠç³ãèš³ãããŸãããïŒãã³ãïŒããã䜿çšã
2幎åçµã£ãŠããŸã 誰ãå²ãåœãŠãããŠããªãã®ã¯æ²ããããšã§ãããããªãéèŠãªæ©èœã®ããã§ã:(
PSïŒæ°åã®ã³ã¡ã³ããèªãã ããCmd + Fãªã©ãè©ŠãããããŸãããããã®æ å ±ã¯èŠã€ãããŸããã§ããã
@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ã§ã¯ãrestargsãtuppleãšããŠå®£èšã§ããããã«ãªããŸããã
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);
};
}
ããããåäžã®ãã©ã¡ãŒã¿ã«å¯ŸããŠã¿ãã«ã€ãã³ããè¿ãé¢æ°ã宣èšãããªãããã®æ¹æ³ã§voidãåŠçããå¿ èŠããããšããå°ããªåé¡ããããŸãããã以å€ã®å Žåã¯ãé åãšããŠæšæž¬ãããæ»ãåã宣èšããå¿ èŠããããŸã:)
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ïŒ 20returnïŒ 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ïŒ 20returnïŒ 20ïŒ 5Ba1ïŒ 2CïŒ 20a2ïŒ 5DïŒ 3BïŒ 0DïŒ 0AïŒ 7DïŒ 0DïŒ 0AïŒ 0DïŒ 0AfunctionïŒ 20foo21ïŒa1ïŒ 3AïŒ 20stringïŒ 2CïŒ 20a2ïŒ 3AïŒ 20booleanïŒïŒ 3AïŒ 20ïŒ 5Bstring ïŒ 5DïŒ 20ïŒ 7BïŒ 0DïŒ 0AïŒ 20ïŒ 20returnïŒ 20ïŒ 5Ba1ïŒ 5DïŒ 3BïŒ 0DïŒ 0AïŒ 7DïŒ 0DïŒ 0AïŒ 0DïŒ 0AïŒ 0DïŒ 0AfunctionïŒ 20bar2ïŒa1ïŒ 3AïŒ 20stringïŒ 2C ïŒ 20a2ïŒ 3AïŒ 20booleanïŒïŒ 3AïŒ 20ïŒ 5BstringïŒ 2CïŒ 20booleanïŒ 5DïŒ 20ïŒ 7BïŒ 0DïŒ 0AïŒ 20ïŒ 20returnïŒ 20ïŒ 5Ba1ïŒ 2CïŒ 20a2ïŒ 5DïŒ 3BïŒ 0DïŒ 0AïŒ 7DïŒ 0DïŒ 0AïŒ 0DïŒ 0AïŒ 0DïŒ 0AfunctionïŒ 20composeïŒ 3CXïŒ 20extendsïŒ 20anyïŒ 5BïŒ 5DïŒ 2CïŒ 20YïŒ 20extendsïŒ 20anyïŒ 5BïŒ 5DïŒ 2CïŒ 20ZïŒ 20extendsïŒ 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ïŒ 20returnïŒ 20functionïŒ 20ïŒ... argsïŒïŒ 20ïŒ 7BïŒ 0DïŒ 0AïŒ 20ïŒ 20ïŒ 20ïŒ 20constïŒ 20yïŒ 20ïŒ 3DïŒ 20fïŒ... argsïŒïŒ 3BïŒ 0DïŒ 0AïŒ 20ïŒ 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ïŒ 0AalertïŒbaz2ïŒ 'a'ïŒ 2CïŒ 20falseïŒïŒïŒ 0DïŒ 0AalertïŒbaz21ïŒ 'a'ïŒ 2CïŒ 20trueïŒïŒïŒ 0DïŒ 0AalertïŒ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)
ãããªããšãããããšãã§ããŸãããããã¯æ¬åœã®çç±ããªãæå¿«ããæžãããšæããŸã
å¯å€ååŒæ°åãå®ãçµã¶ãšãèªåã®ãããžã§ã¯ãçšã«äœæããTypeScriptã³ãŒããäžè¬åããŠãREST APIã®åœ¢ç¶ãå®å šã«å®çŸ©ãã察å¿ããããŒããµãŒããŒãšJavaScriptã®åã«ãã®åœ¢ç¶ãé©çšã§ããããã«ãªããŸãããã®ããã®ã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªã
ãããäžè¬åãããšãèªåã®ã³ãŒããåçŽåã§ããã»ããä»»æã®APIã«å¯ŸããŠåãããšãå®è¡ã§ããŸããããã«é²ãã§ãä»ã®èšèªã®ã¯ã©ã€ã¢ã³ãçšã«Swaggerå®çŸ©ãçæããããšãã§ããŸã...ä»ã®äººã«ã圹ç«ã€å¯èœæ§ããããŸãã ã¯ã¯ã¯ã§ã声ãåºããŠå€¢ãèŠãŠãã
ãã€ãã®å
¥åã«æåããŸãã
https://github.com/kgtkr/typepark/blob/master/src/pipe.ts
@kgtkr ïŒããã¯çŽ æŽãããã§ããïŒ :)
ãã€ãã¿ã€ãã¯ç§ã«ãšã£ãŠTSãã¬ã€ã°ã©ãŠã³ããã¯ã©ãã·ã¥ãããŸãïŒä»ã®äººã¯ããŸãæ©èœããŸããïŒãç§ã¯ãããææ°ã®TSãå¿ èŠãšããŠãããšæããŸããïŒ
TSã¯ãããã€ãã®å垰深床ãšã©ãŒã瀺ããŠããŸã- @ isiahmeadowsããã®ããã«ïŒ26980ãéããããã§ãã
@ tycho01
ãã€ãã¿ã€ãã¯ç§ã«ãšã£ãŠTSãã¬ã€ã°ã©ãŠã³ããã¯ã©ãã·ã¥ãããŸãïŒä»ã®äººã¯ããŸãæ©èœããŸããïŒãç§ã¯ãããææ°ã®TSãå¿ èŠãšããŠãããšæããŸããïŒ
ããã¯ç§ã«ãšã£ãŠããã³ã°ããŸãããããŠç§ã¯ãããæãåºãããã«ããããšã©ãŒãæããããã«åŒ·å¶ããããã«devtoolsã«ããã¯ããªããã°ãªããŸããã§ããã
TSã¯ãããã€ãã®å垰深床ãšã©ãŒã瀺ããŠããŸã- @ isiahmeadowsããã®ããã«ïŒ26980ãéããããã§ãã
ããã¯é¢é£ãããã®ã§ãããç°ãªããã®ã§ãã2ã€ã®çç±ãããæ¡ä»¶ä»ãåã§å¶çŽã解é€ããŸãã
ã€ã³ããã¯ã¹ä»ãã®åãåé€ããã ãã§ã¯ãåã·ã¹ãã ããã¥ãŒãªã³ã°å®å šã§ã¯ãªãç¶æ ã«ããã®ã«ååã§ãªãå Žåã¯ãã³ã¡ã³ããããããããŠãããã«å¿ããŠæŽæ°ã§ããããã«ããŠãã ããã ïŒãã¡ããããããåé€ããããšã¯ææ¡ããŸãããæœåšçãªç¡éã«ãŒãã«ã€ããŠäººã ã«èŠåããããã«ãå éšã§ããé©åã«åŠçããããšãææ¡ããŸããïŒ
èãçŽããŠã¿ããšããã®ãã€ãã¿ã€ãã¯ã (vs...: Params<T[0]>) => ReturnType<Last<T>>
ãå®è¡ããããã®éåžžã«è€éãªæ¹æ³ã®ããã«æããŸãã ãããè¶
ããå埩ïŒäžéãã©ã¡ãŒã¿ãŒãã§ãã¯ãé€ãïŒã¯ãå
¥åã«äŸåããæ»ãã¿ã€ãã§ããããããæçšã«ãªããŸãã
@ tycho01次ã®ãããªãã®ãå ¥åããããšããŠããŸããããã§ãã¿ã€ãã¯åºæ¬çã«æ¬¡ã®ãšããã§ãã
f1, f2, ..., fm, fn -> composed
(a -> b, b -> c, ..., x -> y, y -> z) -> (a -> z)
åŸç¶ã®ãã©ã¡ãŒã¿æ»ãå€ãã©ã¡ãŒã¿ã¯ãåã®ãã©ã¡ãŒã¿ã«äŸåããŠããã®ã§ãããªãã¯ããããæ£ããå ¥åããããã«ãåå¥ã®ãã©ã¡ãŒã¿ãå埩ããå¿ èŠããããŸãããŸããïŒãsããªã@kgtkrïŒæåã®ãã©ã¡ãŒã¿ãšçµäºã®æ»ãå€ãèæ ®ããããã«æã£ãŠããŸãã ïŒ26980ã®ãæ¹åããããããŒãžã§ã³ã§ã¯ã代ããã«ã¢ãã¥ã ã¬ãŒã¿ã䜿çšããããã«æé©åããããããåŒæ°ã®å埩åæ°ã¯å€§å¹ ã«æžããŸããããããæ£ç¢ºã«ãªããŸããã
ïŒ26980ã§ç§ã®ãã®ãèŠããšããããäœãããŠããã®ããå°ãæ確ã«ãªã£ãŠããŸãïŒæ°ã®è¿œè·¡ãå°ãªãïŒãããããç§ããã®æ©èœèŠæ±ãæåºããçç±ã®äžéšã§ãã
@ tycho01 @kgtkrãšããã§ãç§ã¯ãã®ãã°ãä¿®æ£ããã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>);
ãšããã§ãããã¯éã³å Žã§ã¯ã©ãã·ã¥ããŸããã å®éã«ã¿ã€ããã§ãã¯ãè¡ããéåžžã«è¿ éã«å®è¡ããŸãã
æœåšçãª_.flow
ãŸãã¯_.flowRight
ã¿ã€ãã§ãŸã ãã¹ãããŠããŸããããããã¯åºçºç¹ãšããŠæ©èœããã¯ãã§ãã
@ tycho01
å¿
èŠ
typescript @ next
3.0.1 /3.0.2ãæ©èœããªã
ãã®ã¹ã¬ããã®ãããã§ãç§ã¯ãããäœã
çããããã®åé¡ã®è°è«ã«ã»ãšãã©é¢ä¿ã®ãªãæ
å ±ã®æçš¿ããããŠãã ããã å¯å€ååŒæ°ã®çš®é¡ãå¿
èŠãªããããã®ãã£ã¹ã«ãã·ã§ã³ããã©ããŒããŠãã人ã¯ããããããŸãã ãã®åé¡ããã©ããŒããŠããçç±ãšã¯é¢ä¿ã®ãªããéå»2æ¥éã«10é以äžã®ã¡ãŒã«ãåãåããŸããã
ç§ã«åæãã人ãä»ã«ãããšæããŸãã ãããŸã§ã¯ãã¹ãã ã«è²¢ç®ããããªãã£ãã®ã§ãåæ¢ããããšãæãã§ããŸããã ããããçå£ã«ãååã§ãã
PSãã®éç¥ããè©«ã³ããŸããç§ãšåãããã圌ãã«ããããããŠãã人ã«ã¯
@Yuudaari Lodashã®_.flow
ãRamdaã®_.compose
ãªã©ãå
¥åããããšãããã®ãã°ã®åååã®1ã€ã§ãããå
¥åãæåãããããšã¯ããã®åé¡ã®è§£æ±ºã®äžéšã§ããããšãææããŸãã å®éããããå
ã®åé¡ã®èª¬æã«èšèŒãããŠããçç±ã®1ã€ã§ãã
å®éãçŸæç¹ã§ã¯ãå¯å€ååŒæ°ã§ä»æ¥ååšããåé¡ã®99ïŒ
ã¯ãæ©èœã§ã¯ãªã人éå·¥åŠã«ãããšç§ã¯èããŠããŸãã ç§ãã¡ã¯ãå
¥åããããšãã§ããŸãFunction.prototype.bind
ãšPromise.all
ããªãã¯ç¹°ãè¿ãè¡ãããšãã§ããã€ã³ããã¯ã¹ä»ãã®ã¿ã€ãã®æ··åç©ãšå®å
šã«ãæ¡ä»¶ä»ãã®ã¿ã€ããããã³ååž°ïŒ Append
ã®ããã®ãªã¹ãå埩Function.prototype.bind
ãããã³Promise.all
ã¯åçŽãªå埩+ Append
ïŒã«ãªããŸãããããããã®ã¯éåžžã«åä»ã§å®åçã§ãã
å§ãŸã£ãã°ããã®ãã®ãšèª¬æãããã€ãºããã«è¿œå ããããšããŠããªãããã§ã¯ãããã¯åœŒãããã®ã§ãªãå Žåã§ããããªããå人çã«å¿é ããŠããããã°ãååšããçç±ã®äžéšã«é¢ä¿ããããã«ã話é¡ã¯æè¡çã§ãã
ããã§çºè¡šãåŸ
ã£ãŠãã人ã
ã¯å€§ããªãã¥ãŒã¹ãèŠéãããšæããŸã-ä»ãå¯èœã«ãªã£ãConcat<T, U>
ã¯[...T, ...U]
ãŸã£ããåãããã«æ©èœããããšã
Pipe
ãµãã¹ã¬ããã¯ãããã§èŠæ±ããæ©èœã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã«é¢ãããã®ã§ãã ä»æ¥ããã®ã¹ã¬ããã®ãã€ã³ãã«å°éããããšã«ã€ããŠã§ãã
ããã¯ããã®ã¹ã¬ãããéããŠãæªããªãããšãæå³ãããšæãã®ã§ãããããããã¯è³ªåããè¯ãæ©äŒã§ã-人ã ã¯ãŸã ãã®ææ¡ã«äœãæãã§ããŸããïŒ
[ããã¯]ããã¯éåžžã«åä»ã§å®åçã§ã
ããã䜿çšããã»ãšãã©ã®åã¯ååž°èªäœã䜿çšãããããããããäœæãã人ã¯ééããªããããã«ç²ŸéããŠããŸããããšã³ããŠãŒã¶ãŒã¯TSã®å埩ãååšããããšãç¥ããªããŠããäºåå®çŸ©ãããåã®ã©ã€ãã©ãªã䜿çšããŠããã³ããšã³ããäœæããå¯èœæ§ããããŸãã
ãã®æç¹ã§ããããããã®ææ¡ã¯äž»ã«ããã©ãŒãã³ã¹ãæ¹åããå¯èœæ§ããããŸããïŒ
ãŸããããããªããžã§ã¯ãã䜿çšããŠãåã·ã¹ãã ãã ãŸããŠãæå³ãããšããã«ååž°ãå®è¡ãããŠããŸããïŒ ããã¯ç§ã«ã¯ããªãããããŒã®ããã§ãã ç§ããã®ãããªæ©èœã䜿çšããå ŽåïŒç§ã¯ããã§ãããããã¯ç¡é¢ä¿ã§ãïŒãåŸã§å£ããããšã¯ãããŸãããïŒ
第äºã«ããããã®åé¿çã䜿çšããããšã¯...å奜çã§ã¯ãããŸããã ããã¯ããŸãèªã¿ã«ããïŒç¹ã«ãããæžããªãã£ã人ã«ãšã£ãŠïŒããã®çµæãç¶æããã®ã¯æšãã«èŠããŸãã
åé¿çããããšããçç±ã ãã§ãæå³ããããèªã¿ããããä¿å®å¯èœãªæ¹æ³ã§åãæ©èœãè¿œå ããææ¡ã«é Œãããã®ã¯ãªãã§ããïŒ
ãã®åé¿çã®ååšããã®ææ¡ãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãšèŠãªãåå ã«ã¯ãªããªããšæããŸãããããšãããã ã£ããšããŠãããªããã®æ··ä¹±ã«ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãå¿ èŠãªãã®ã§ããããã
@Yuudaari
ç·šéïŒã³ã³ããã¹ãã®ãªã³ã¯ãè¿œå ããŸãã
ãŸããããããªããžã§ã¯ãã䜿çšããŠãåã·ã¹ãã ãã ãŸããŠãæå³ãããšããã«ååž°ãå®è¡ãããŠããŸããïŒ ããã¯ç§ã«ã¯ããªãããããŒã®ããã§ãã ç§ããã®ãããªæ©èœã䜿çšããå ŽåïŒç§ã¯ããã§ãããããã¯ç¡é¢ä¿ã§ãïŒãåŸã§å£ããããšã¯ãããŸãããïŒ
ç§ãæè¿æåºãããã°ãèŠãŠãã ããïŒïŒ26980ã ãã¿ãŒã³ãçåèŠããŠããã®ã¯ããªãã ãã§ã¯ãããŸããã ããã§ã¯å°ã話é¡ããå€ããŠããŸãããæ°è»œã«ãã£ã€ã ã鳎ãããŠãã ããã
ååž°çãªãã®ãçµäºãããã©ãããå€æããæ¹æ³ã«ã¯ãå°ãæ°åŠãé¢ä¿ããŠããããšã«æ³šæããŠãã ããïŒãããããããéåžžã«åŸ®åŠãªéããããäž»ãªçç±ã®1ã€ïŒã
第äºã«ããããã®åé¿çã䜿çšããããšã¯...å奜çã§ã¯ãããŸããã ããã¯ããŸãèªã¿ã«ããïŒç¹ã«ãããæžããªãã£ã人ã«ãšã£ãŠïŒããã®çµæãç¶æããã®ã¯æšãã«èŠããŸãã
åé¿çããããšããçç±ã ãã§ãæå³ããããèªã¿ããããä¿å®å¯èœãªæ¹æ³ã§åãæ©èœãè¿œå ããææ¡ã«é Œãããã®ã¯ãªãã§ããïŒ
ãã®åé¿çã®ååšããã®ææ¡ãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãšèŠãªãåå ã«ã¯ãªããªããšæããŸãããããšãããã ã£ããšããŠãããªããã®æ··ä¹±ã®ããã«ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãæãŸãªãã®ã§ããããïŒ
äºå®äžArray.prototype.map
ã§ãããšããäžè¬çãªã±ãŒã¹ã§ã¿ãã«ãå埩ããåçŽåãããæ¹æ³ã¯ååšããŸãããããã¯åºæ¬çã«ç§ã®ããŒãºã«ã¯åœ¹ã«ç«ã¡ãŸããã§ããïŒã¢ãã¥ã ã¬ãŒã¿ãå¿
èŠã§ããïŒã
ç§ã¯å人çã«ãããã®ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã欲ããã§ãïŒ
[...First, ...Second]
ãä»ããŠ2ã€ã®ãªã¹ããé£çµããŸãã[...Values, Item]
ãä»ããŠå€ãè¿œå ããŸããT extends [...any[], infer Last]
ä»ããŠæåŸã®èŠçŽ ãæœåºããŸãã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ã䜿ãå§ãããšããç§ã®åŸåã¯_ã¡ããã©ãã_ãæžãããšã§ããïŒ ïŒ ...T
ïŒå¯å€ååŒæ°typevarã¿ãã«ã®æ§æã«ãªãããšãæåŸ
ããŠã ãŸãããããå
¥ãããšãé¡ã£ãŠããŸã:)
[...T, ...U]
æ°ãã䜿çšæ³ãèŠã€ããŸããïŒHTMLãã«ããŒãæ£ããå
¥åããŸãã å
·äœçãªäŸãšããŠã <video>
ã®åã¯æ¬¡ã®ããã«ãªã£ãŠããå¿
èŠããããŸãã
src
å±æ§ãããå ŽåïŒ<track>
èŠçŽ src
å±æ§ããªãå ŽåïŒ<source>
èŠçŽ audio
ãŸãã¯video
åå«èŠçŽ ãèš±å¯ãããŠããªãããšãé€ããŠã芪ã®ã³ã³ãã³ãã¢ãã«ã«åŸã£ãŠ0å以äžã®èŠçŽ ãããã¯åºæ¬çã«ãã®ã¿ã€ããšåãã§ãããä»æ¥TypeScriptã§ãããè¡šçŸããæ¹æ³ã¯ãããŸããã
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ããã«å¯Ÿããå¯äžã®å®éã®è§£æ±ºçã¯ãåºæ¬çã«ãpromiseé¢æ°ãäœæãããã®ããªã¢ã³ãã«ãã¹ãŠã®å¯èœãªã¿ã€ããæåã§æå®ããããšã§ã-ã©ãããããããªã¢ã³ãããåèªãã眲åãå®éã«æäŸããå¯äžã®æ¹æ³ã¯ããªãŒããŒããŒããæå®ãããå®è£ 眲åãæå®ããããšã§ãããã ãããã®ããã«ã·ã°ããã£ãæå®ããå Žåãæž¡ãåŒæ°ã«åºã¥ããŠãã©ã®ãªã¿ãŒã³ã¿ã€ããæåŸ ããå¿ èŠãããããåŒã³åºãå ã«ç¥ãããæ¹æ³ã¯ãããŸããã
ããã¯ãæ®ãã®ãã©ã¡ãŒã¿ãŒãæåŸã®ãã©ã¡ãŒã¿ãŒã«ãããªãåŸãªããšããäºå®ã«ãã£ãŠæªåããŸãïŒã€ãŸãã (cb, ...args)
ã¯æå¹ã§ããã (...args, cb)
ã¯æå¹ã§ã¯ãªãããã眲åãå
éšçã«å
±çšäœåã§ãã£ãŠããå®éã«ã¯ã§ããŸãããç©äºãæ£ããåºãã-ããšãã°ã cb
ãåžžã«function promisify<T, V extends any[]>(fn: (cb: (err: Error | null, res?: T) => void, ...args: V)): (...args: V) => T
ãšããŠpromisifyãšå
¥åããæåã®åŒæ°ã§ãããå°ãªããšãåãæ»ãå¿çãæã€çœ²åã®å
±çšäœåãååŸã§ããå Žåã¯ãããªãç°¡åã§ããããããæåŸã®ãã©ã¡ãŒã¿ã§ãããããã§å®è¡ã§ããããšã¯ããŸããããŸããã
@ Qix-ã·ããªãªã¯ïŒ24897ã«ãã£ãŠæå¹ã«ãªããŸãã TS3.0ã§å®è£ ãããŸããã
@ahejlsberg OofïŒ çŽ æŽããããããããšãâ¥ïž
é·ãéåŸ ã£ãŠããŸãã...ããããä»æ¥ã¯å¯å€ååŒæ°ã®çš®é¡ãæžãããšãã§ããŸãã TSã¯ãæ©èœããè€éãªåãäœæããã®ã«ååæçããŠããŸãã ããã§ãã©ã ãã®ã«ã¬ãŒãã³ã³ãã£ãããã³ã³ããžã·ã§ã³ããã€ãã®ã¿ã€ããæžãã®ã«æéããããŸããã
ãããŠçŸåšã ts-toolbeltã«å梱ãããŠããŸãã
ãã ãããã®ææ¡ã¯ãäžè¬çãªã¿ãã«æäœãã¯ããã«ç°¡åã«ããããã®åªããæ§æç³è¡£ã§ãã
ãã§ã«medium.comã«ãããŸããïŒ URLïŒ
Mediumã«é¢ããå ã®èšäºããããŸãããããŒãã¹ã¯å«ãŸããŠããŸããããªããžããªã«ãããŸãã ãŸããäœæ²ããã€ããã«ã¬ãŒãäœæããããã®å°ããªããŒã«ããã¹ãŠäœæããæ¹æ³ã«ã€ããŠã説æããŸãïŒsmileïŒ
@ 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
å¯å€ååŒæ°åãå®è£ ãããŠãããšããŠããåã®2ã€ã®äŸã§ã¯ããããã³ã³ãã€ã«ãšã©ãŒãçºçããŸãããåŒæ°ã3ã€ãããªãå Žåãå¯å€ååŒæ°åã®ãã€ã³ãã¯äœã§ããã
ããªãã®äŸã¯ãå¯å€ååŒæ°ãå¿ èŠãªçç±ã瀺ããŠããã¯ãã§ããæ¢åã®TSã³ãŒãã§å®è¡ã§ããå Žåãããã¯åå ããŸã£ããå©ããŸããã
@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ã ããç§ã¯ããªãã®ææ¡ã§ãããããããšããŸãããããããç解ããããšãã§ããŸããã§ããã
ãåé¡ã¯ãã¯ã©ã¹ã®ctorã®ãã©ã¡ãŒã¿ãŒãæ¡åŒµããããšããŠããããšã§ããããã¯ãåã®é åããããšãããŸã§æ©èœããŸãããctorãã©ã¡ãŒã¿ãŒã«å¯ŸããŠããããæ¡æ£ã§ããŸãããã
Class Test {
constructor(x: number, y: string) {}
}
let ExtendedClass = extendCtor<[number, string], [number]>(Test);
let instance = new ExtendedClass(1, '22', 2);
æŽæ°ïŒ ctoré¢æ°ã§ã¹ãã¬ããã䜿çšããŠãæ©èœããããšãæ°ã«ããªãã§ãã ããã
ããããœãªã¥ãŒã·ã§ã³ã®ãªã³ã¯ã§ã
å¯äžã®åé¡ã¯ãTSãã»ãŒæ¯åã¯ã©ãã·ã¥ããããšã§ãïŒ|
ãããTypeScriptã®èšãããšã§ã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>
}
TypeScriptã®lib.d.ts
å¥ã®æ¹æ³ã§å®£èšãããŠããçç±ã¯ãããŸããïŒ
ååž°çãªæ¡ä»¶åã¯ãµããŒããããŠããªãããã䜿çšããŠããŸããïŒãã®èª¬æã«ã€ããŠã¯ãïŒ26980ãåç §ããããããããªãããã«æ瀺ãããã®ã³ã¡ã³ããåç §ããŠãã ããïŒã çŸåšã®äº€å·®ç¹ã®æ»ãã¿ã€ãã䜿çšããå Žåã¯ãïŒ28323ããããŸãã
@jcalz Minus
ã¿ã€ãã®åäœã瀺ãéããã¹ããäœæããŸããã 4ç§æªæºã§Minus
216000åå®è¡ããŸãã ããã¯ãTSãååž°åãéåžžã«ããŸãåŠçã§ããããšã瀺ããŠããŸãã ããããããã¯ããæè¿ã®ããšã§ãã
ã©ãããŠïŒ ããã¯AndersïŒtadaïŒïŒhttps://github.com/microsoft/TypeScript/pull/30769ïŒã®ãããã§ãã 圌ã¯ç§ãæ¡ä»¶ä»ãã¿ã€ãããã€ã³ããã¯ã¹ä»ãæ¡ä»¶ïŒã¹ã€ããã®ãããªïŒã«åãæ¿ããããšãèš±å¯ããŠãããŸããã å®éã®ãšãããts-toolbeltã®ããã©ãŒãã³ã¹ã¯6ååäžããŸããã 圌ã«ãšãŠãæè¬ããŠããŸãã
ãããã£ãŠãæè¡çã«ã¯ãts-toolbeltã䜿çšããŠ@kimamulaã®åãå®å šã«æžãçŽãããšãã§ããŸãã è€éãã¯OïŒnïŒã«åŸããŸãã
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'},
]>
libã¯ãŸããTypeScriptããã®ãªãŒããŒãããŒãé²ãIteration
ã§ååž°ãå®å
šã«ããŸãã ã€ãŸãã I
ã40
è¶
ãããšããªãŒããŒãããŒãã Pos<I>
ã¯number
çãããªããŸãã ãããã£ãŠãååž°ãå®å
šã«åæ¢ããŸãã
ç§ãæžããåæ§ã®ååž°åïŒ Curry
ïŒã¯Ramdaã«
ã¡ãªã¿ã«ããããžã§ã¯ãã®ããŒãžã§ã¢ããã€ã¹ãããããšãããããŸããïŒ@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
ç§ã¯èšã£ãã
TL; DRãã¿ãã«åãã¬ã¹ãåŒæ°ãããããããé åã¿ã€ããéã¬ã¹ãåŒæ°ã®ã¿ãã«æšè«ãååž°åãšã€ãªã¢ã¹=å€æ°ååŒæ°ã®ãµããŒãã¯å®éã«ã¯å¿ èŠãããŸãã
ããããæ¢åã®ããŒã«ã§ã¯åçŽã«æå¹ã«ã§ããªããŠãŒã¹ã±ãŒã¹ããããã©ãããç¥ãããã§ãã
Concat<T extends any[], U extends any[]>
å
¬åŒã«ç¥çŠãããããŒãžã§ã³ãå
¥æãããŸã§ãããã¯äŸç¶ãšããŠé¢é£æ§ããããŸãã ä»åŸã®ååž°ååç
§æ©èœããããç§ãã¡ã«äžãããšã¯æããŸããããïŒæ£åŒã«ïŒå¥ã®æ¹æ³ã§èšãããããšãå¬ããæããŸãã
Concat<>
å®è£
ã¯ãããããŸãããïŒ
ãããšããããã§ã®ããŒã¯ãŒãã¯ãå ¬åŒã«ç¥çŠãããŠãããã®ã§ããããã
ç§ã®äž»åŒµã¯ãããšããããå®å šã«ãå ¬åŒã«ç¥çŠãããŠããªãããšããŠããåºæ¬çã«ããªããçŸæç¹ã§æãããšãã§ãããã¹ãŠïŒãŸãã¯ã»ãšãã©ãã¹ãŠïŒïŒãè¡ãããšãã§ãããšããããšã§ãã
ããããç§ã¯ãå ¬åŒã«ç¥çŠãããããåžžã«å¥œãŸããã¹ãã ãšæããŸã...è¯ãç¹ã ç§ã¯ãããã®ååž°åãšã€ãªã¢ã¹ãïŒabïŒäœ¿çšããããšã«ããŸãã«ãæ £ããŠããŸã
ç§ã¯äžè¬çã«ãæ¬ç©ã®ãšã¬ã¬ã³ããªæ§æã奜ã¿ãŸããããããã°ããã®ãããªããšããããã³ã«ãïŒå€ãã®å Žåããžã¥ãã¢ã®ïŒããŒã ã¡ãŒãã«ãçŸç¶ã®ä¹±çšãå¿ èŠãšããçŽããããæå®ã®åã«ã€ããŠäœãèµ·ãã£ãŠããã®ãã説æãç¶ããå¿ èŠããªããªããŸãã ãã®æ··ä¹±ã¯ãç§ã®çµç¹ã§TypeScriptãäŒéããç§ã®èœåããŸãã¯å°ãªããšããããã®äœ¿çšæ³ã«æªåœ±é¿ãåãŒããŸãã
ããã§å€§ããªðïŒ
ãã®æ©èœã¯ãšãŠãéèŠã§ãã
@AnyhowStep
ç§ã®äž»åŒµã¯ãåºæ¬çã«ãçŸæç¹ã§å¿ èŠãªãã¹ãŠïŒãŸãã¯ã»ãšãã©ãã¹ãŠïŒïŒãå®è¡ã§ãããšããããšã§ãã
ã¹ãã¬ãããã©ã¡ãŒã¿ãè€æ°ã®åäžãã©ã¡ãŒã¿ãšäžç·ã«å ¥åããããšããä»æ¥ã®TSã§ç°¡åã«éæã§ãããšãã蚌æ ã¯èŠåœãããŸããã
@ matthew-åŠéšé·ã¯å®å šã«çå®ã§ã¯ãããŸããã ããã¯ããªããããçšåºŠéæãããããããªãäŸã§ãã
ç§ãç解ããŠããããã«ã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[]]
ãšæšæž¬ãããŠããŸãããããã¯åœ¹ã«ç«ã¡ãŸããã
ãŸããC ++ã¯ãã§ã«ãã¹ãŠã®Head<>
ãšCons<>
ãééããŠãããããC ++ã®ããã«15幎éGreenspunã®10çªç®ã®ã«ãŒã«ãå°éããå¿
èŠããªãããšã«ã泚æããããšæããŸããéåžžã«äŸ¿å©ã§ã¯ãªãŒã³ãªå¯å€ååŒæ°ãã³ãã¬ãŒãæ§æãèæ¡ããŸããã ç§ãã¡ã¯ïŒæ°çŸå¹Žã®ïŒéçºè
ã®æéãç¯çŽããããããæé«ã®éšåãåãåºãããšãã§ããŸãã
äŸãã°ãå¯å€åŒæ°ã®åãç°ãªãæã£ãŠããçš®é¡ããªãã¯ã¿ã€ããæåŸ
ãããŠããå¯å€åŒæ°ã®åå€æ°ã䜿çšããããšã¯ã§ããŸããã®ã§ãã¿ã€ããšã¯ç°ãªããC ++ã§ã®ãã®extends any[]
TSã€ã³ãããã«ãããC ++ã¯ãçç¥èšå·æŒç®åã§å²ãŸããåŒã®å
éšã§å¯å€ååŒæ°åå€æ°ã«èšåããããšã«ãããã¿ãã«ãããã/å§çž®ã§ããŸãã ããã¯ããããããããªããžã§ã¯ãã¿ã€ãã®ã¿ãã«ã®ä»£æ¿æ段ã§ãã
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ãã®ããã«pingã
äœè«ã§ãããå¯å€ååŒæ°ã®çš®é¡ããªãããã«åãã©ã¡ãŒã¿ãŒã§äœ¿çšã§ããªãå Žåã§ããã¿ãã«åã®åã¬ãã«ã®æ¡æ£æäœãããã ãã§ãç§ã®ããŒã ã«ãšã£ãŠå€§ããªå©ãã«ãªããŸãã ç§ãã¡ã®åé¡é åã§ã¯ããäœããã®æ§é ãæã€é åããéåžžã«äžè¬çã§ãã ãã®æäœãæ©èœããå Žåãããã¯ç§ãã¡ã«ãšã£ãŠç©äºãå€§å¹ ã«åçŽåããã§ãããïŒ
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<>
ïŒãã®äŸã§ã¯ååž°çã«å®çŸ©ãããã¿ãã«åã®åéåã«è©äŸ¡ãããŸãïŒã®ãããªåã¬ãã«ã®é¢æ°ãèšè¿°ã§ããããã«å¯å€ååŒæ°ã䜿çšãããšãããã«åçŽåã§ããŸãã
ãŸããã¿ãã«åã®åã»ãŒããªé£çµãªã©ããµããŒãããããšãéåžžã«åœ¹ç«ã¡ãŸãïŒOPã§èª¬æãããŠããŸãïŒã äžèšã®ã¿ã€ãã䜿çšããã«ã¯ãçŸåšãã¿ãã«å šäœãåäžã®ã¿ãã«ãªãã©ã«åŒã§äœæããå¿ èŠããããŸãã çŸåšãéšåçã«æ§ç¯ããŠé£çµããããšã¯ã§ããŸããã ã€ãŸãã以äžã®æäœã¯ä»æ¥ã¯æ©èœããŸããããå®éã«æ©èœããããšãé¡ã£ãŠããŸãã
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é¢æ°ãèšè¿°ã§ããŸãã åŒæ°ã®æ°ã
ã¿ãã«ã®ã¿ãã«ãåããã¿ãã«ãé£çµããConcat <> implãäœæããããšãå¯èœã§ãã var-arg Concat <>ã¿ã€ãã
ä»æ¥ã¯ã§ããªãããšã§ã¯ãããŸããã ååž°åãšãã«ããŒé¢æ°ãæžãå¿ èŠãããå Žåã§ãããããè¡ãããšãã§ããŸãã
vscodeã§ãããã®ååž°åã䜿çšãããã³ã«ãTSã¯CPUã匷å¶çµäºãããããŸãã¯ãã³ã°ããã ãã§ãã ãããäž»ãªåé¡ã§ããçç±ããªãTSãéããªããããŠããããã«æããŸãã
ãã¶ããåãæžããŠãã人ã ã¯ãããæé©åããã®ã«ååãªããšãããŠããŸãããïŒ
ãã®ã¹ã¬ããã«ããŸã䟡å€ããããããªãå€ãäŒè©±ãã¹ãã ããããã©ãã°ãããããããªãã®ã§ãããJavaScriptã§ã¯ååž°çãªæ¡ä»¶åã®èšç®ã«ã³ã¹ããããããšèããããšããããŸãïŒãã®ã¹ã¬ããã§èŠã€ããŸããïŒ
ããã¯èšã£ãŠãïŒã¯ã¬ã€ãžãŒã«èããããããããŸãããïŒãTSã¯ãã§ã«å€§ããæé·ããŠããã®ã§ãããè¯ããã®ãæ±ããã®ãåççã§ãããããåã·ã¹ãã ãåŸæŒãã§ããããã«ãTSãå¥ã®èšèªã§æžãçŽãæãæ¥ãã®ãããããŸããã
ããªãã¯ç°¡åã«æžãããšãã§ããŸã
Concat<>
ãšå ¥åããäœãConcat3<>
ã¿ã€ãã䜿çšããŠãConcat<>
ã
説æããŠããConcat<>
ã¿ã€ãã®å®è£
ãæäŸããŠããã ããŸããïŒ Cons<>
ãæžãã®ã¯ç°¡åã§ããã Concat<>
ã¯ïŒç§ã«ãšã£ãŠïŒããã»ã©ç°¡åã§ã¯ãªãã®ã§ãããªããäœãæ³åããŠããã®ãèŠãŠã¿ããã§ãã
Concat3<>
ã Concat4<>
ãªã©ã«é¢ããŠã¯ãå¯å€ååŒæ°ã®çš®é¡ããããããé·æçã«ã¯ãããã®ãããªæ°åã®ããªã¢ã³ããäœæããå¿
èŠããªãããšãæåŸ
ãããŸãã ðãããããããã®é©åãªå®è£
ãä»æ¥å¯èœã§ããå Žåãããã¯åççãªäžæçãªå¯Ÿçã«ãªããŸãã
2ã€ã®ã¿ãã«ãå®æçã«é£çµããå Žåã¯ã
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ãè¿ããŸã
ãã¡ãããçŽ æŽãªååž°ã¯ããŸãšããªé·ãã®ã¿ãã«ã§æ倧深床ãšã©ãŒã«ã€ãªãããŸãã ãããã£ãŠãts-toolbeltã§ååž°ææ³ã䜿çšããããç®çã®æ·±ããŸã§ã³ããŒããŠè²Œãä»ãããã©ã³ããªã³ã䜿çšããŸãã
ããã¯ç§ãçšéã«ãªã³ã¯ãããŠããã¬ã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
é¢é£ããåé¡::
æ®å¿µãªããããã®æŠç¥ã¯RESTãã©ã¡ãŒã¿ãŒã§ã¯æ©èœããŸããã ãããã¯é åã«å€æãããŸãïŒ
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
ã
ããã¯ãã¿ãã«ã®æåŸã®èŠçŽ ãé åã§ãããã¿ãã«ã®RESTãã©ã¡ãŒã¿ãŒãæã€é¢æ°ã«ç¹å¥ãªå Žåãããå Žåã«ãµããŒãã§ãããšæããŸãã
ãã®å Žåãé¢æ°åŒã³åºãã«ãããæ£ããåã®è¿œå ã®åŒæ°ãé åãšäžèŽããããã«ãªããŸãã
ããããããã¯è€éãããŠäŸ¡å€ããªãããã§ãã
ããã«ã¯2ã€ã®åé¡ããããŸãã
curried()
ã¯é
åãåãå
¥ããŸããã c
restãã©ã¡ãŒã¿ãŒã«[true, false]
ããããšã¯ã curried('foo', ...[true, false])
ã«ãã£ãŠå®è¡ã§ããŸããããã®ææ¡ã§ã¯TypeScriptã§å€±æããŸãã å Žåã«ãã£ãŠã¯ã¿ã€ãã³ã°ãœãªã¥ãŒã·ã§ã³ãæäŸã§ããªãããšããããŸãããééã£ã人ãæäŸããããšã¯ãå§ãããŸãããcurried()
ã¯ã b
ãªãã§ã¯åŒã³åºãããšãã§ããŸãããã c
åŒã³åºãããšãã§ããŸãã ããããããšã¯ãäžæ£è¡çºã«ã€ãªãããŸãã TypeScriptã¯curried()
ã(...items: [string, boolean[]] | [boolean[]])
ããšãç¥ã£ãŠããŸããã[true, false]
ãc
ã«æž¡ããŠïŒäžèšã®åé¡ã解決ãããšä»®å®ïŒã curried([true, false])
ãæå®ããŠãã b
ã¯undefined
èšå®ãããŸããã c
ã[true, false]
ã«èšå®ããŸããã b
ãtrue
ã c
ã[false]
ïŒæ¬¡ã®ä¿®æ£ããå§ãããŸãã
[number, string, boolean[]] | [number, boolean[]]
ïŒã®ãŠããªã³ã¿ãã«ãæšæž¬ããªãã§ãã ããã 代ããã«ã [number, string, boolean[]] | [number]
æšæž¬ããŸããã€ãŸãããã¹ãŠã®ãªãã·ã§ã³ãšæ®ããå«ãå®å
šãªçœ²åã®1ã€ã®ã±ãŒã¹ãæåŸãé€ãåãªãã·ã§ã³ã«1ã€ãæåŸãšæ®ãã®ãªãã±ãŒã¹ã«1ã€ãã€æšæž¬ããŸãã[t1, t2, t3, ...arr]
ã«ã€ããŠèããŸãïŒãå
¬éãããšãããšæããŸãããããããå¿
èŠã¯ãããŸããã å
éšãšããŠãã®ãŸãŸäœ¿çšã§ããŸãïŒãããIDEã§ã¿ã€ãã衚瀺ããæ¹æ³ãåŠçããå¿
èŠããããŸãðïŒããããããã¹ãŠã®èŠæ ãšæçºçãªåŸãçŽ æŽãããææ¡ïŒ ããããšãðïŒããªããèœã¡çãããããã«ãããã¯ç§ã3ã€ã®çµµæåã§å¿çããGitHubã§ã®æåã®åé¡ã§ã-ðãðãâ€ïžïŒã
ããã¯ãçŸåšany
ã䜿çšããå¿
èŠãããAngularInjectorã§éåžžã«åœ¹ç«ã¡ãŸãhttps://github.com/angular/angular/issues/37264
ãã®äŸã§ã¯ãAãBãCã¯ãåäžã®...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ã®2çªç®ã®ãã©ã¡ãŒã¿ãŒãæŽæ°ããŠãæçµçã«Typescriptã§é©åã«å ¥åã§ããããã«ããŠãã ããã
@Grifforkæ£èŠè¡šçŸã解æããŠããã£ããã£ã°ã«ãŒããããã€ããããææ¡ããå¿ èŠãããããšã
ããã¯ãçŸåš
any
angle / angularïŒ37264ã䜿çšãããã®äŸã§ã¯ãAãBãCã¯ãåäžã®
...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 pipe
ã¡ãœãããã©ã¡ãŒã¿ãçžäºã«äŸåããŠããRxJS
ãããªãã®ã§ããã®æ§æãã©ã®ããã«äœ¿çšãããããèããããšããŠããŸãã
pipe(map<T, V>(...), map<V, U>(...), filter(...), ...)
ã 圌ããä»ããŠããããšãšã¯éãæ¹æ³ã§ãããã©ã®ããã«ã¿ã€ãããŸããïŒ ïŒå¯å€ååŒæ°ã®é·ããç°ãªãæ°åè¡ã®å
¥åïŒ
@ahejlsbergãæåºããPRã䜿çšãã@gioraguttããã¯ããŸããããšæããŸãããééã£ãŠããå¯èœæ§ããããŸãð
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 ïŒ
ãŸããã©ã¡ãã®å Žåã§ããã³ã¡ã³ããå«ãŸããŠãããã«ãªã¯ãšã¹ãã§ãããå ±æããããšã匷ããå§ãããŸãã
å¯å€ååŒæ°ã¿ãã«ã¿ã€ãã¯èšèªãžã®çŽ æŽãããè¿œå ã§ããåªåã«æè¬ããŸãïŒ
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
ãã ããäžèšã®ã«ã¬ãŒã§ã¯ç·ç§°æ©èœã¯æ©èœããŸããã
ãã®PRããã®ç¹å®ã®åé¡ã解決ãããšã¯æããªãã
PRã§ããã¯æ©èœããŸã
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
æšè«ãç解ã§ããªããŸããªã±ãŒã¹ã§è§æ¬åŒ§ãåé¿ã§ããããã«ããããã«ããŸã£ããæ°ããæŠå¿µïŒã€ãŸããRESTã¿ã€ãã®ãã©ã¡ãŒã¿ãŒïŒãæ¬åœã«å¿ èŠã ãšã¯æããªãã§ãã ããã
@ahejlsbergãªãã»ã©ã äžéšã®ã©ã€ãã©ãªïŒåè¿°ã®RxJSïŒããã®æ©èœãæäŸããããã«åé¿çã䜿çšãããããç§ã¯å°ããŠããŸããã ããããããã¯æéã§ãã
bar<T1>(t1: T1);
bar<T1, T2>(t1: T1, t2:T2);
bar<T1, T2, T3>(t1: T1, t2:T2, t3: T3, ...t: unknown) { ... }
ã ããä»ã圌ãã¯ããã«åºå·ãããããŠãŒã¶ãŒã«è§ãã£ããå ¥åããããã®ã©ã¡ããã§ããããã¯é倧ãªå€æŽã§ãããããã»ã©çŽæçã§ã¯ãããŸããã
ãã®äŸã䜿çšããçç±ã¯ãããã§ãã®ã¿ãã«ã®ã¿ã€ããå®çŸ©ããã®ã¯ç°¡åã ããã§ãã ããã«è§æ¬åŒ§ã1ã€ãããã«1ã€
foo<[number, string]>([12, '13']);
ããã§ã¯ãå€éšããèŠãå Žåãã¿ãã«ããã®RESTãã©ã¡ãŒã¿ãŒãåç §ããŠããããšã¯ããã»ã©æçœã§ã¯ãããŸããã
foo<[number, string]>(12, '13');
ããããããªããèšã£ãããã«ãæšè«ã«ãããç解ãããã°ããããã®äºçŽ°ãªã±ãŒã¹ã¯ãŠãŒã¶ãŒããã®å€æŽãå¿ èŠãšããŸããã ãããã圌ããããããæ瀺çã«èšå®ãããã©ããã¯ããããŸãããããã¯åœŒã次第ãªã®ã§ãããã§ãé倧ãªå€æŽãšããŠã«ãŠã³ããããŸãã ããããããã¯libã®é¢å¿äºã§ããããã®å€æŽã®é¢å¿äºã§ã¯ãããŸããã
ãšã¯ãããå€åŽãã1ã€ãã€å®çŸ©ãããå
åŽã«...
ã§åºå¥ãããåäžã®é
åã§ããRESTãã©ã¡ãŒã¿ãŒãããå Žåãåãæ¹æ³ã§1ã€ãã€ãžã§ããªãã¯ã«ããããšãã§ããªãã®ã¯å¥åŠã ãšæããŸããå€åŽã¯åäžã®é
åãå
åŽã¯...
ã§åºå¥ãããŸãã
ãã€ããŒãªæ§æã®äžäžèŽã¯ãåå¥ã®ãµããŒãã³ã¹ãã®äŸ¡å€ããããŸãã
芪åã TSãèšç»ãç«ãŠãŠãããšããçš®é¡ã䜿çšããããšã¯æ£ããèšèšäžã®æ±ºå®ã§ãã
æ®ãã®ãã©ã¡ãŒã¿ãŒã®ãµããŒãã§ãããä»ã§ã¯ãã£ãšå€ãã®ããšãèµ·ãããããããªããšæããŸã
èšèªéçºè
ãšãŠãŒã¶ãŒã®äž¡æ¹ã«ãšã£ãŠæ··ä¹±ã ã®ãœãªã¥ãŒã·ã§ã³ãå¿
èŠã§ãã
ãã®åé¡ããããŠã¢ã³ããŒã¹ã¯ãããé¿ããŠéåžžã«ããŸãä»äºãããŸãã
ãã ããããšã«ãããè€é[...T]
ã®ä»£ããã«T
ã è±åžœïŒ
ïŒäº€å·®åãçµ±åãããã°ãèŠãŠã¿ãŸããã
æ¡ä»¶åã®æšå®å€æ°ã¯ãå³ç«¯ã®äº€å·®åãè¿ããŸã
åŒæ°ããŸãã¯é
åã®åéåã¯åéåã®é
åã§ã¯ãããŸãããïŒ ç§ãã¡ã¯ãŸã
åã·ã¹ãã ã«äž»èŠãªã·ã§ãŒããããŒããããŸããïŒ
éã2020幎6æ19æ¥ã«ã¯ãåå10æ41GyÅriã·ã£ãŒã³ãã«ã®[email protected]ã¯æžããŸããïŒ
@ahejlsberghttps ïŒ//github.com/ahejlsbergãªãã»ã©ã ç§ãå°ããŠããã®ã¯
äžéšã®ã©ã€ãã©ãªïŒåè¿°ã®RxJSïŒã¯ããããæäŸããããã«åé¿çã䜿çšããŸãã
æ©èœã ããããããã¯æéã§ããããŒ
ïŒt1ïŒT1ïŒ;ã㌠ïŒt1ïŒT1ãt2ïŒT2ïŒ;ã㌠ïŒt1ïŒT1ãt2ïŒT2ãt3ïŒT3ã... tïŒäžæïŒ{...} ã ããä»ã圌ãã¯ããã«åºå·ãããããŠãŒã¶ãŒã«è§ãã£ããå ¥åããããã®ã©ã¡ããã§ãã
ããã¯ããã»ã©çŽæçã§ã¯ãããŸããããã®äŸã䜿çšããçç±ã¯ãããã§ã¯ç°¡åã ããã§ã
ãã®ã¿ãã«ã®ã¿ã€ããå®çŸ©ããŸããã ããã«è§æ¬åŒ§ã1ã€ãããã«1ã€foo <[æ°å€ãæåå]>ïŒ[12ã'13 ']ïŒ;
ããã§ã¯ãã¿ãã«ããã®RESTãã©ã¡ãŒã¿ãŒãåç §ããŠããããšã¯ããã»ã©æçœã§ã¯ãããŸããã
å€ããèŠãfoo <[æ°å€ãæåå]>ïŒ12ã '13'ïŒ;
â
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/microsoft/TypeScript/issues/5453#issuecomment-646490130 ã
ãŸãã¯è³Œèªã解é€ãã
https://github.com/notifications/unsubscribe-auth/AAWYQIMTTB6JEPSQFUMTMDTRXMJD5ANCNFSM4BTBQ7DQ
ã
ãã¡ãããç§ã¯åœŒã®å£åŸã«ã¯ã»ã©é ãã§ããã ãŸãã
ç§ã®çµéšã§ã¯ãtypescriptã®è€éãã®å€ãã¯ãå€ãã®ïŒèå³æ·±ãã確ãã«åœ¹ç«ã€ïŒæ©èœãç¬èªã®æŠå¿µãšããŠç¹å¥ã«äœ¿çšãããŠãããšããäºå®ã«èµ·å ããŠããŸãã
ãã ãããã®è€éãã¯æ¬è³ªçã«æ©èœã®æ°ã®é¢æ°ã§ã¯ãããŸããã
代ããã«ãèšèªã¯ããããã®ç¹æ®ãªã±ãŒã¹ãç°¡åã«æšæž¬ããããstdïŒã¿ã€ãïŒã©ã€ãã©ãªã«å®è£
ãããã§ããããã倧ãããããå
æ¬çãªæŠå¿µã«åºã¥ããŠèšèšããããšãã§ããŸãã
ãã¡ãããæãäžè¬çãªãã®ãããªæŠå¿µã¯ãäŸååãå®å
šã«å®è£
ããããšã§ãããããããä»ã®ãã¹ãŠãå°ãåºãããšãã§ããŸããããããŸã§é²ãå¿
èŠã¯ãããŸããã
C ++ãšãçšåºŠã¯å°ãªããRustã瀺ããããã«ãããã€ãã®å€§èŠæš¡ã§äžè²«æ§ã®ããæŠå¿µã«ããã倧éã®æ©èœãç¡æã§æäŸãããŸãã
ããã¯ãOCamlãšHaskellïŒãããŠç§ã¯FïŒã ãšæããŸããïŒïŒãå€ã¬ãã«ã§ãã¡ããã©ã¿ã€ãã¬ãã«ã§è¡ã£ãããšã«äŒŒãŠããŸãã
åã¬ãã«ã®ããã°ã©ãã³ã°ã¯ãç¹å®ã®æ©èœãæäŸããããã«è¿œå ãããã®ã§ã¯ãªããèšèªã«åãããŠèšèšãããŠããéããæããããšã¯ãããŸããã
C ++ 14/17ã®æ©èœã¯ãæ§æãçŽç²ã«éå»ã®æè·ç©ã«ãããã®ã§ããããšãé€ãã°ãéåžžã«çŽæçã§ãã
å
æ¬çãªæŠå¿µãå
ã®èšèšã«è¿œå ãããå¯èœæ§ããããŸãã èšèšåŸ
ééãã¯ãã§ã«è¡ãããŠããã倧ããªãªã¹ã¯ãåããã«äžè²«æ§ãè¿œå ããããšã¯ã§ããŸãã
ããã¯éäºææ§ã ç§ã¯èšèªãã¶ã€ã³ã«é¢ããçæã«åæããŸã
å
šäœïŒTSã¯åŠçã«ãã£ãŠèšå®ãããåºæºããããªãé ãã§ãã誰ãã§ããŸãã
ããã«åæããŸããïŒã ãã°ãççŸããããããããŸã
äœçŸäžãã®ãããã¯ã·ã§ã³ã³ãŒãããŒã¹ã®åºç€ã§ãã ãã ã®äºå®
éçºè
ã¯èšèªãžã®äŸ¿å©ãªè¿œå ãæãä»ãããšãã§ããŸã
誀ã£ãŠãããã®ãã°ãä¿®æ£ããããšãªããç§ã®è¬èãªæèŠã§ã¯ãçŽ æŽãããã§ã
ãããŠå°æ¬ã«å€ããã TSã¯ããã§ã¯C ++ãšåãèšèšã®è€éããæã£ãŠããŸããã
è¡šçŸåã·ã¹ãã ã¯ç¶æ³ãæªåãããŸãã
éã2020幎6æ19æ¥ã«ã¯ãåå12æ47åããããPiaterã®[email protected]ã¯æžããŸããïŒ
ãã¡ããç§ã¯åœŒã®å£åŸã«ã¯ã»ã©é ãã§ãããç§ã¯æ¬æãè¡šããŠå察ããŸã
@ahejlsberghttps ïŒ//github.com/ahejlsbergã䜿çšããŸãã
ç§ã®çµéšã§ã¯ãtypescriptã®è€éãã®å€ãã¯å€ãã®ïŒèå³æ·±ãã確ãã«åœ¹ç«ã€ïŒæ©èœãç¬èªã®ã³ã³ã»ãããšããŠç¹å¥ãªã±ãŒã¹ã«å ¥ããããŸãããã®è€éãã¯ãæ¬è³ªçã«æ©èœã®æ°ã®é¢æ°ã§ã¯ãããŸãã
ããã©ïŒ
代ããã«ãèšèªã¯ãã倧ãããããå æ¬çãªãã®ãäžå¿ã«èšèšããããšãã§ããŸã
ãããã®ç¹æ®ãªã±ãŒã¹ãç°¡åã«æšæž¬ã§ããæŠå¿µããŸãã¯
stdïŒã¿ã€ãïŒã©ã€ãã©ãªã«å®è£ ãããŠããŸãããã¡ãããæãäžè¬çãªãã®ãããªæŠå¿µã¯ãå®å šã«å®è£ ããããšã§ãã
äŸååãä»ã®ãã¹ãŠã掟çãããããšãã§ããŸããã
ãããŸã§è¡ãå¿ èŠã¯ãããŸããïŒ
C ++ãšããŠããããŠçšåºŠã¯å°ãªãããRustã瀺ããããã«ãããã€ãã®å€§èŠæš¡ãª
äžè²«ããã³ã³ã»ããã«ãããããããã®æ©èœãç¡æã§æäŸãããŸãã
ããã¯ãOCamlãšHaskellïŒãããŠç§ã¯FïŒã ãšæããŸããïŒïŒãè¡ã£ãããšãšäŒŒãŠããŸã
ã¿ã€ãã¬ãã«ã ãã®å€ã¬ãã«ãåã¬ãã«ã®ããã°ã©ãã³ã°ã¯ããããããã§ããéããæããããšã¯äœããããŸããã
ç¹å®ã®æ å ±ãæäŸããããã«åãçµãã®ã§ã¯ãªããèšèªã«åãããŠèšèšãããŠããŸã
ç¹åŸŽã
C ++ 14/17ã®æ©èœã¯ãæ§æãé€ããŠéåžžã«çŽæçã§ãã
ããã¯çŽç²ã«æŽå²çãªæè·ç©ã«ãããã®ã§ããâ
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/microsoft/TypeScript/issues/5453#issuecomment-646543896 ã
ãŸãã¯è³Œèªã解é€ãã
https://github.com/notifications/unsubscribe-auth/AAWYQIMWYLGGCWPTDBZJR4TRXMX4RANCNFSM4BTBQ7DQ
ã
@ polkovnikov-phåœé¢ã®åé¡ã«åæã§ããŠããããã§ã:)
解決çãšããŠã¯ãããæ éã«èšèšãããåã·ã¹ãã ã«åŸã ã«ç§»è¡ããããšãæ€èšãã䟡å€ããããšæããŸãã çµå±ã®ãšãããã¡ãžã£ãŒããŒãžã§ã³ã¯éèŠã§ããã代æ¿æ段ã¯ãC ++ 20ã§ããã¯ã©ã¹ã¿ãŒ**ã§çµããããšã§ã-åé€ã§ããªã以åã®è©Šã¿ã®2ã€ã®ã¬ã€ã€ãŒã®äžã«ããã«ããŸãèšèšãããæ©èœãè¿œå ããçŽ æŽãããè©Šã¿ã§ãããŸã 決å®è«çã«è§£æã§ããªãæ§æã
ãããã¯ãã¹ãŠãã®ã¹ã¬ããã§ã¯ãããã¯ããå€ããŠãããããã§èª¬æããŠã
åŠçããµãã¿ã€ãã³ã°ãžã®æ£ããã¢ãããŒããç解ããã®ã«æ°å幎ããããŸãããmlsubåã·ã¹ãã ã¯ãTypeScriptãæåã«ãªãªãŒã¹ãããŠããããã6幎åã«äœæãããŸããã ããã¯ãå æ¬çãªæŠå¿µãæã€ã¯ã©ã¹ãã€ã³ã¿ãŒãã§ãŒã¹ãåéåãããã³äº€å·®åã®åºç€ã§ããå¯èœæ§ããããŸãã
ãã ããæ¡ä»¶åãããããšãå¿ããªãã§ãã ããã æ£åŒãªã»ãã³ãã£ã¯ã¹ãæäŸããŠããè«æããé²è¡ç¶æ³/ä¿å蚌æãåããæ¡ä»¶ä»ãåã䜿çšããæå°åã·ã¹ãã ã«ã€ããŠèª¬æããŠããè«æã¯ãããŸããã ããã¯ã倱æããè©Šã¿ãå°å·ããããšã«ãŸã æ¥ãããããå±ã§ããç§åŠè ãšé¢ä¿ãããã®ã§ã¯ãªãããšæããŸãã ããªãã®ææ¡ããããã®äž»èŠãªäºææ§ã®ãªãããŒãžã§ã³ã2040幎代ã«äœããããšä»®å®ãããªãã°ãåŠçãæ¡ä»¶ä»ãã¿ã€ãã«æ £ãããšããç§ã¯åæããããšãã§ããŸãã
ããã§ãªããã°ããæ éã«èšèšãããåã·ã¹ãã ãã¯èšèªããæ¡ä»¶ä»ãåãåé€ããå¿ èŠããããDefinitelyTypedã®60ïŒ ãå€æããŠããããã眮ãæããããã«éžæããã代æ¿æ段ã䜿çšããããšã¯èª°ã«ãã§ããªããšæããŸãã ïŒãããŠããããå¯äžã®åé¡ã§ã¯ãªãã®ã§ããããããã«æ°åè¡ããŸããïŒ
å¯äžã®å®è¡å¯èœãªè§£æ±ºçã¯ãã©ããããããTSã«äŒŒãå¥ã®ããã°ã©ãã³ã°èšèªãäœæããããšã§ãããã©ããããããïŒã³ãŒããæžãã®ããã楜ããã ãã§ãªãïŒéçºè ã«ããã䜿çšããããã«èªæããããšã§ãã ã©ã€ã¢ã³ã¯ä»¥åãTSã®æ¹åã®ããã«ãã®ã¢ãããŒããæšå¥šããããšãéåžžã«å£°é«ã«èšã£ãŠããŸããã
æãåèã«ãªãã³ã¡ã³ã
ãã®åé¡ã¯ãTS 4.0ã§äºå®ãããŠããïŒ39094ã§ä¿®æ£ãããŠããŸãã