è©ŠããŠã¿ãŠãã ããïŒ npm install yortus-typescript-typeof
å·®åã衚瀺ããŸãïŒããã
TypeScriptã®åæšè«ã¯ãã»ãšãã©ã®å Žåãéåžžã«ããŸãã«ããŒããŸãã ãã ããã³ã³ãã€ã©ãå¿ååãæšæž¬ã§ãããšããŠããå¿ååãåç §ããæ確ãªæ¹æ³ããªãç¶æ³ãããã€ãæ®ã£ãŠããŸãã ããã€ãã®äŸïŒ
// Mapping to a complex anonymous type. How to reference the element type?
var data = [1, 2, 3].map(v => ({ raw: v, square: v * v }));
function checkItem(item: typeof data[0] /* ERROR */) {...}
// A statically-typed dictionary. How to reference a property type?
var things = { 'thing-1': 'baz', 'thing-2': 42, ... };
type Thing2Type = typeof things['thing-2']; // ERROR
// A strongly-typed collection with special indexer syntax. How to reference the element type?
var nodes = document.getElementsByTagName('li');
type ItemType = typeof nodes.item(0); // ERROR
// A factory function that returns an instance of a local class
function myAPIFactory($http: HttpSvc, id: number) {
class MyAPI {
constructor(http) {...}
foo() {...}
bar() {...}
static id = id;
}
return new MyAPI($http);
}
function augmentAPI(api: MyAPI /* ERROR */) {...}
// Declare an interface DRY-ly and without introducing extra type names
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
// prop2 shares some structure with prop1
prop2: typeof MyInterface.prop1.big.complex; // ERROR
}
1ã€ã®äŸã¯ãå¿ååããã©ã¡ãŒã¿ãŒãšããŠåãåãé¢æ°ã宣èšããããšã§ãã ãã©ã¡ãŒã¿ã®åã¢ãããŒã·ã§ã³ã§äœããã®æ¹æ³ã§åãåç
§ããå¿
èŠããããŸããããããªããšããã©ã¡ãŒã¿ãany
ãšå
¥åããå¿
èŠããããŸãã
åŒãè©äŸ¡ããã«ç®çã®åãæšè«ããåæååã䜿çšããŠãããŒå€æ°ã宣èšããŸãïŒããã¯ãå®è¡æã®å¯äœçšãæãŸããåæšè«ã ãã§ããããéèŠã§ãïŒã äŸãã°ïŒ
let dummyReturnVal = null && someFunction(0, ''); // NB: someFunction is never called!
let ReturnType = typeof dummyReturnVal; // Now we have a reference to the return type
ãã®åé¿çã«ã¯ããã€ãã®æ¬ ç¹ããããŸãã
dummyReturnValue
ã®ãããªå€æ°ãå°å
¥ããå¿
èŠããããŸãïŒ_ïŒæ³šïŒãã®è§£æ±ºçã¯ïŒ4233ã§ãã§ã«ææ¡ãããŠããŸããããã®åé¡ã«ã¯ãææ¡ãå¿ èŠããšããã¿ã°ãä»ããããŠãããä»ã«ãå¯æ¥ã«é¢é£ããåé¡ãããã€ãããããããã®å¥ã®åé¡ããããŸããïŒ_
typeof
ã®ãªãã©ã³ããä»»æã®åŒã«ããããšãã§ããŸãã ããã¯ã if (typeof foo() === 'string')
ã®ãããªå€ã®äœçœ®ã«ããtypeof expr
ã§ãã§ã«èš±å¯ãããŠããŸãã ãã ãããã®ææ¡ã§ã¯ã typeof
ãåã¯ãšãªãšããŠåäœçœ®ã§äœ¿çšããå ŽåïŒããšãã°ã type ElemType = typeof list[0]
ïŒãä»»æã®åŒã䜿çšããããšãã§ããŸãã
ãã®ææ¡ã¯ãä»æ§ã®çŸåšã®æèšãšãã§ã«å¯æ¥ã«äžèŽããŠããŸãã
ã¿ã€ãã¯ãšãªã¯ããªããžã§ã¯ããªãã©ã«ãé¢æ°å®£èšãåå空é宣èšãªã©ã®ããŸããŸãªæ§é ã«ãã£ãŠçæãããå¿åã¿ã€ãããã£ããã£ããã®ã«åœ¹ç«ã¡ãŸãã
ãããã£ãŠããã®ææ¡ã¯ãäžèšã®äŸã®ããã«ãçŸåšæäŸãããŠããªãç¶æ³ã«ãã®æçšæ§ãæ¡åŒµããŠããã ãã§ãã
ã»ãã³ãã£ã¯ã¹ã¯ãä»æ§4.18.6ã§ãã§ã«è¿°ã¹ãããŠãããšããã§ãã
'typeof'æŒç®åã¯ãä»»æã®åã®ãªãã©ã³ããåããStringããªããã£ãåã®å€ãçæããŸãã åãæåŸ ãããäœçœ®ã§ã¯ããtypeofããåã¯ãšãªïŒã»ã¯ã·ã§ã³3.8.10ïŒã§äœ¿çšããŠãåŒã®åãçæããããšãã§ããŸãã
ææ¡ãããéãã¯ã以äžã«åŒçšãããŠããã»ã¯ã·ã§ã³3.8.10ã«é¢é£ããŠãããæã¡æãããããã¹ããåé€ããã倪åã®ããã¹ããè¿œå ãããŸãã
ã¿ã€ãã¯ãšãªã¯ãããŒã¯ãŒãtypeofãšããã«ç¶ãåŒã§æ§æãã
ãŸããåŒã¯ãèå¥ååŒïŒã»ã¯ã·ã§ã³4.3ïŒãŸãã¯ããããã£ã¢ã¯ã»ã¹åŒïŒã»ã¯ã·ã§ã³4.13ïŒã®åé åŒãšããŠåŠçããããã®çµæãæ¡åŒµåïŒã»ã¯ã·ã§ã³3.12ïŒã«ãªããŸãã ä»ã®éçåä»ãæ§é ãšåæ§ã«ãåã¯ãšãªã¯çæãããJavaScriptã³ãŒãããæ¶å»ãããå®è¡æã®ãªãŒããŒãããã¯è¿œå ãããŸããã
匷調ããªããã°ãªããªãç¹ïŒãããä»æ§ã«å«ãŸããŠãããšæããŸããããèŠã€ãããŸããã§ããïŒã¯ãåã¯ãšãªã¯ãªãã©ã³ããè©äŸ¡ããªããšããããšã§ãã ããã¯çŸåšåœãŠã¯ãŸããããè€éãªåŒã«ã€ããŠãåœãŠã¯ãŸããŸãã
ãã®ææ¡ã¯ãæ°ããæ§æãå°å
¥ãããã®ã§ã¯ãªããã¯ãšãªã§ããåŒã®ã¿ã€ãã®å¶éãtypeof
ã«ããã ãã§ãã
// Mapping to a complex anonymous type. How to reference the element type?
var data = [1, 2, 3].map(v => ({ raw: v, square: v * v }));
function checkItem(item: typeof data[0]) {...} // OK: item type is {raw:number, square:number}
// A statically-typed dictionary. How to reference a property type?
var things = { 'thing-1': 'baz', 'thing-2': 42, ... };
type Thing2Type = typeof things['thing-2']; // OK: Thing2Type is number
// A strongly-typed collection with special indexer syntax. How to reference the element type?
var nodes = document.getElementsByTagName('li');
type ItemType = typeof nodes.item(0); // OK: ItemType is HTMLLIElement
// A factory function that returns an instance of a local class
function myAPIFactory($http: HttpSvc, id: number) {
class MyAPI {
constructor(http) {...}
foo() {...}
bar() {...}
static id = id;
}
return new MyAPI($http);
}
type MyAPI = typeof myAPIFactory(null, 0); // OK: MyAPI is myAPIFactory's return type
function augmentAPI(api: MyAPI) {...} // OK
// Declare an interface DRY-ly and without introducing extra type names
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
// prop2 shares some structure with prop1
prop2: typeof (<MyInterface>null).prop1.big.complex; // OK: prop2 type is {anonymous: {type: {}}}
}
ã«å¯ŸããŠïŒæ§æã®çŸåŠã貧匱ã§ãã åã ã®ã±ãŒã¹ã«å¯ŸåŠãã代æ¿æ§æã¯ãïŒ6179ãïŒ6239ãïŒ4555ãããã³ïŒ4640ã§ææ¡ãããŠããŸãã
For ïŒä»ã®æ§æã¯ãç¹å®ã®å Žåã«é©ããŠããå ŽåããããŸããããããã¯ãã¹ãŠäºãã«ç°ãªããããããã1ã€ã®ç¹å®ã®åé¡ã®ã¿ã解決ããŸãã ãã®ææ¡ã¯ãããããã¹ãŠã®åé¡ã§çºçããåé¡ã解決ããéçºè ã¯æ°ããæ§æãåŠã¶å¿ èŠããããŸããã
å察ïŒåã®äœçœ®ã«ããåŒã¯æ··ä¹±ãæããŸãã
For ïŒTypeScriptã¯ãã§ã«typeof
ã2ã€ã®æå³ã§ãªãŒããŒããŒãããŠããŸããã¿ã€ãã¯ãšãªãšããŠãã¿ã€ãã¹ã¯ãªããã¯ãã§ã«ã¿ã€ãäœçœ®ã®åŒãåãå
¥ããè©äŸ¡ããã«ãã®ã¿ã€ããååŸããŸãã ããã«ããããã®åé¡ã§çºçããåé¡ã解決ã§ããããã«ããã®åŒã®å¶çŽãç·©åãããŸãã
ã«å¯ŸããŠïŒããã¯ãéåžžã«é·ãè€æ°è¡ã¿ã€ãã®ã¯ãšãªãäœæããããã«æªçšãããå¯èœæ§ããããŸãã
察象ïŒåã¯ãšãªã§ãããè¡ãæ£åœãªçç±ã¯ãããŸããããããè€éãªåŒãèš±å¯ããæ£åœãªçç±ããããŸãã ããã¯åºæ¬çã«ããŒãã£ã³ãã¡ãŠã©ãŒã®æå¹åãšæ瀺ã§ãã
ããã¯ãçŽç²ã«äžäœäºææ§ã®ããå€æŽã§ãã æ¢åã®ã³ãŒãã¯ãã¹ãŠåœ±é¿ãåããŸããã typeof
ã®è¿œå æ©èœã®äœ¿çšã¯ãªããã€ã³ã§ãã
å·®åãèŠããšãå€æŽãéåžžã«å°ããããšãããããŸãã ã³ã³ãã€ã©ãŒã¯ãç §äŒãããŠããåããã§ã«èªèããŠããŸããããã¯ãéçºè ã«ãããã衚瀺ããã ãã§ãã ããã©ãŒãã³ã¹ãžã®åœ±é¿ã¯ãããããã ãšæããŸãããããããã¹ãããæ¹æ³ãããããŸããã
ãã®ææ¡ãèšèªãµãŒãã¹ãšããŠå®è£ ããTypeScriptã®ããŒãžã§ã³ã䜿çšããããã«VSCodeãèšå®ããŸããããã¹ãããéãããã¹ãŠã®æ§æã®åŒ·èª¿è¡šç€ºãšã€ã³ããªã»ã³ã¹ã¯å®ç§ã§ãã
.d.ts
ãã¡ã€ã«ã§è€éãªåŒãçºçããå¯èœæ§ããããŸãtypeof
ã®ãªãã©ã³ãã¯ãIIFEãå«ãä»»æã®åŒããŸãã¯ã¡ãœããæ¬äœãªã©ãåããã¯ã©ã¹åŒã«ããããšãã§ããŸãããããè¡ãçç±ã¯èããããŸãããå
éšã§ãã£ãŠãããã¯ããšã©ãŒã§ã¯ãããŸããã .d.ts
ãã¡ã€ã«ïŒ typeof
ã¯ãã¢ã³ããšã³ãã³ã³ããã¹ãã§äœ¿çšã§ãã䟿å©ã§ãïŒã ãããã£ãŠããã®ææ¡ã®çµæã¯ããã¹ããŒãã¡ã³ãã¯åšå²ã®ã³ã³ããã¹ãã§ã¯è¡šç€ºã§ããªãããšããããšã¯ããã¯ãå³å¯ã«ã¯çå®ã§ã¯ãªããšããããšã§ãã
ã³ã³ãã€ã©ã«ã¯ã次ã®ãããªåŠçã«å¿ èŠãªãã¹ãŠã®ããžãã¯ããã§ã«çšæãããŠããããã§ãã
function foo<X,Y>(x: X, y: Y) {
var result: typeof foo(x, y); // ERROR: 'result' is referenced in its own type annotation
return result;
}
ãããŸãã§ã¯ãããŸããã ã¯ãšãªã®åŒã«äžèŽãããªãŒããŒããŒããéžæããŸãã
declare function foo(a: boolean): string;
declare function foo(a: number): any[];
type P = typeof foo(0); // P is any[]
type Q = typeof foo(true); // Q is string
ã€ã³ããªã»ã³ã¹ãªã©ã䜿çšããŠVSCodeã§ããããã°ãããã¬ã€ããæ¹æ³ãå¿ èŠãªå Žåã¯ãããã«ãã¬ã€ã°ã©ãŠã³ããªããžããªããããŸãã
ã¿ã€ãP=typeof fooïŒ0ïŒ; //Pã¯any[]
ã¿ã€ãQ=typeof fooïŒtrueïŒ; //Qã¯æååã§ã
å€ã®ä»£ããã«åãåŒæ°ãšããŠäœ¿çšããæ¹ãããæå¹ãªæ§æã ãšæããŸãã
type P = typeof foo(number); // P is any[]
type Q = typeof foo(boolean); // Q is string
åŒæ°ãšããŠå€ã§ã¯ãªãåãæå®ãããããé¢æ°ãåŒã³åºãããŠããªãããšãããæ確ã«ãªããŸãã ãã1ã€ã®ãã€ã³ãã¯ããããŸãããå°ãªãããšã§ãã typeof foo(false)
ã䜿çšãã人ãããã°ã typeof foo(true)
ã䜿çšãã人ãããŸãã åŒæ°ãšããŠåãããå Žåã人ã
ã¯typeof foo(boolean)
ããæžãããšãã§ããŸããã
@tinganhoãŸãã«ïŒ
ïŒ5185ã§typeof foo("abc")
ãæžãããšã¯ã§ããŸãã
ããã§"abc"
ã¯ã·ã³ã°ã«ãã³æåååã§ã
@tinganhoç§ã¯ããªãã®ã¢ã€ãã¢ã«ããã€ãã®èããäžããŠããŸããããããŠç§ã¯ãã®ææ¡ã«ã€ããŠç§ã奜ãããã€ãã®ããšããããŠããªãã®ææ¡ã«ã€ããŠç§ã奜ãä»ã®ããšãèŠãŸãã ããªãã®ææ¡ã¯ããªããäžããçç±ã®ããã«è¯ãã§ãïŒããåçŽã§ããæ確ãªæ§æãããææ§ããå°ãªããé¢æ°åŒã³åºãã®ããã«èŠããŸããïŒã ç§ã®ææ¡ã§ç§ã奜ãã®ã¯ãæ°ããæ§æãå°å ¥ãããŠããªããããããŒãµãŒ/ãã§ãã«ãŒã«è€éããå ãããªãããšã§ãããŸããåŒæ°ã«åçŽãªååããªããããè€éãªã·ããªãªããµããŒãããŸãã
foo(number)
æ§æã®ãããªãã®ããæ¢åã®åŒè§£æã¡ã«ããºã ã䜿çšããŠæžãéåžžã«ç°¡åãªæ¹æ³ããããšãããã©ãã§ããããã ããã§ãå®éšãšããŠãæ°ããåŒ_unaryas_ãå°å
¥ããŸããã as T
ãšæžãã ãã§ã (null as T)
ã®çç¥åœ¢ã«ãªããŸãã ããªãã¯åºæ¬çã«ã_'å€ã¯æ°ã«ããŸããããåŒã«ã¿ã€ãX'_ãæãããããšèšã£ãŠããŸãã
ãã®å€æŽïŒç§ã¯ãã¬ã€ã°ã©ãŠã³ããªããžããªã«å®è£ ããŸããïŒã䜿çšãããšãææ¡ãããæ§æã«éåžžã«è¿ããã®ãèšè¿°ã§ããŸãããããã§ãéåžžã®åŒãšããŠè§£æãããŸãã
type P = typeof foo(as number); // P is any[]
type Q = typeof foo(as boolean); // Q is string
let prop2: typeof (as MyInterface).prop1.big.complex; // prop2 type is {anonymous: {type: {}}}
ããã¯ç°¡åãªå®éšã§ããã åçã®æ§æã¯æ¬¡ã®ããã«ãªããŸãïŒãã ããããã¯å®è£ ããŠããŸããïŒã
type P = typeof foo(<number>); // P is any[]
type Q = typeof foo(<boolean>); // Q is string
let prop2: typeof (<MyInterface>).prop1.big.complex; // prop2 type is {anonymous: {type: {}}}
2çªç®ã®æ§æã¯_nullaryã¿ã€ãã®ã¢ãµãŒã·ã§ã³_ãšåŒã°ããå ŽåããããåŒ<T>
ã¯(<T> null)
ã®çç¥åœ¢ã§ãã
@yortus ãå é±ããã®ææ¡ã«ã€ããŠè©±ãåã£ãã 以åã«æçš¿ããªãã£ãããšããè©«ã³ããŸãã ã³ã³ã»ã³ãµã¹ã¯1ã§ãããããšãã°ãé¢æ°ã®æ»ããã¯ã©ã¹åŒã®ã€ã³ã¹ã¿ã³ã¹ã¿ã€ããªã©ãäžéšã®ã¿ã€ããåç §ã§ããªããšããåé¡ããããŸãã 2.åã®äœçœ®ã«åŒãè¿œå ããããšã¯ãç§ãã¡ãæ £ããŠããããšã§ã¯ãããŸããã
@tinganhoã®ææ¡ãç§ãã¡ã話ãåã£ããã®ã§ããã å®è£ ã¯ãããããã£ãšè€éã«ãªãã§ãããããç§ã¯ãããããå£åœãããè¯ããšæããŸãã æ°ããåé æŒç®åãè¿œå ãããããã£ã¹ãæ§æã䜿çšãããããããšã¯ãååã䜿çšããã ãã®å Žåã»ã©æŽç·ŽãããŠããŸããã
ä»æ¥ã®ã¹ããŒã¬ã³ã§ããªãé·ãéè°è«ãããŸããã ããã§ã®ãPRã®åãå ¥ããã¯ããå®è£ ãããŸãã«ãã¯ã¬ã€ãžãŒã§ããããšãå€æããªããšä»®å®ããŠPRãåãå ¥ãããã§ãã
@tinganhoã®ææ¡ã¯ïŒå°ãªããšãä»ã®ãªãã·ã§ã³ãšæ¯èŒããŠïŒããªãè¯ãããã§ãããããå®è£ ããæ«å®çãªPRãå¿ èŠã§ãã
ããªãããŒãªããšã¯ã f(number)
ãšf(0)
ã®æ»ãåã解決ããããã«å®å
šã«å¥åã®ã³ãŒããã¹ãæãããããªããšããããšã§ãããéè² è·è§£æ±ºã¢ã«ãŽãªãºã ã¯å®å
šã«çµã¿èŸŒãŸããŠããŸãã _types_ã®ã»ããã§ã¯ãªãã_expressions_ã®ã»ããã§åäœããŸãã ããããå°ã泚æãæãã°ãããã¯ç°¡åãªã¯ãã§ãã
æ»æã®åºæ¬çãªèšç»ã¯æ¬¡ã®ãšããã§ãã
typeof
ã解æãããšãã«ææ³ãæ¡åŒµããŠãé¢æ°åŒã³åºããããããã£ã¢ã¯ã»ã¹ãã€ã³ããã¯ã¹ä»ãããããã£ã¢ã¯ã»ã¹ã®ããã«èŠãããã®ãèš±å¯ããŸãparseType
é¢æ°ã䜿çšããŸãã ããã«ããTypeNode
ãäœæãããŸãããåã¯ãšãªã®ã³ã³ããã¹ãã§è§£æãããåã§ããããšã瀺ããã©ã°ãããŒãã«èšå®ããŸãcheckExpression
ããã®ãã©ã°ããã§ãã¯ããéåžžã®åŒåŠçã®ä»£ããã«getTypeFromTypeNode
ãåŒã³åºããŸãã@ mhegazy ã @ RyanCavanaughã¯ãããŒã ã話ãåã£ãã³ãŒããŒã±ãŒã¹ã®æ°ãããããªãã®ã§ã説æã®ããã«ããã«ããã€ãæããããšãã§ããŸããïŒ ä»¥äžã«å€æ°ã®äŸããªã¹ãããããããã«typeof
æäœã®çµæã§ãããšæããããã®ãšãçãããã±ãŒã¹ã«çå笊ãä»ããŠã³ã¡ã³ãããŸããã
var data = [1, 2, 3];
const LOBOUND = 0;
type Elem1 = typeof data[0]; // number
type Elem2 = typeof data[999999]; // number or ERROR?
type Elem3 = typeof data[1+2]; // ERROR or number?
type Elem4 = typeof data[LOBOUND]; // ERROR or number?
var tuple: [number, string] = [123, 'abc'];
type Elem4 = typeof tuple[0]; // number or number|string?
type Elem5 = typeof tuple[1]; // string or number|string?
type Elem6 = typeof tuple[999999]; // number|string or ERROR?
const ABC: 'a-b-c' = 'a-b-c';
let dict = { 'a-b-c': 123, 'd-e-f': true };
type Prop1 = typeof dict['a-b-c']; // number
type Prop2 = typeof dict['d-e-f']; // boolean
type Prop3 = typeof dict[ABC]; // ERROR or number or any?
// A simple function
declare function f1(n: number): string[];
type Ret1 = typeof f1(number); // string[]
type Ret2 = typeof f1(0); // ERROR or string[]?
// An asynchronous function that either accepts a callback or returns a Promise
declare function f2(n: number): Promise<string[]>;
declare function f2(n: number, cb: (err?: any, result?: string[]) => void): void;
type Ret3 = typeof f2(number); // Promise<string[]>
type Ret4 = typeof f2(number, any); // void
type Ret5 = typeof f2(number, Function); // ERROR: Function not assignable to callback
type Ret6 = typeof f2(number, (err: any, result: string[]) => void); // void
type Ret7 = typeof f2(number, (...args) => any); // void
// A special function-like object
interface Receiver {
(data: string[]): void;
transmogrify(): number[];
}
declare function f3(n: number, receiver: Receiver): Promise<void>;
declare function f3(n: number, callback: (err?: any, result?: string[]) => void): void;
type Ret8 = typeof f3(number, Receiver); // Promise<void>
type Ret9 = typeof f3(number, any); // ambiguous? or picks first overload?
type Ret10 = typeof f3(number, Function); // ERROR
type Ret11 = typeof f3(number, (...args) => any); // void since not assignable to Receiver
// A function with parameter destructuring
interface CartesianCoordinate {/***/}
interface PolarCoordinate {/***/}
declare function f4({ x: number, y: number }): CartesianCoordinate;
declare function f4({ r: number, t: number }): PolarCoordinate;
type Ret12 = typeof f4(any); // ambiguous? or picks first overload?
type Ret13 = typeof f4({x;y}); // CartesianCoordinate
type Ret14 = typeof f4({r;t}); // PolarCoordinate
type Ret15 = typeof f4({x;r;t;y}); // ambiguous? or picks first overload?
// Type-ception: is there anything wrong with typeof-in-typeof?
declare function f5(n: number, receiver: Receiver): Promise<void>;
declare function f5(n: number, callback: (err?: any, result?: string[]) => void): void;
function myCallback(err, result) {/***/}
var myReceiver: Receiver;
type Ret16 = typeof f5(number, typeof myReceiver); // Promise<void>
type Ret17 = typeof f5(number, typeof myCallback); // void
ã€ãŸããäžèšã®typeof (<MyInterface> null).prop1.big.complex;
ã®äŸã§ãã
äžèšã®ã³ã¡ã³ããããããã¯ç¯å²å€ã§ããããµããŒããããªãããšãããããŸãã ããã¯æ£ããã§ããïŒ
var data = [1, 2, 3];
const LOBOUND = 0;
type Elem1 = typeof data[0]; // number
type Elem2 = typeof data[999999]; // number
type Elem3 = typeof data[1+2]; // ERROR, only literals allowed here
type Elem4 = typeof data[LOBOUND]; // number when const resolution is done, otherwise any
var tuple: [number, string] = [123, 'abc'];
type Elem4 = typeof tuple[0]; // number
type Elem5 = typeof tuple[1]; // string
type Elem6 = typeof tuple[999999]; // number|string
const ABC: 'a-b-c' = 'a-b-c';
let dict = { 'a-b-c': 123, 'd-e-f': true };
type Prop1 = typeof dict['a-b-c']; // number
type Prop2 = typeof dict['d-e-f']; // boolean
type Prop3 = typeof dict[ABC]; // number when const resolution work is done, otherwise any
// A simple function
declare function f1(n: number): string[];
type Ret1 = typeof f1(number); // string[]
type Ret2 = typeof f1(0); // error, 0 is not a type
// An asynchronous function that either accepts a callback or returns a Promise
declare function f2(n: number): Promise<string[]>;
declare function f2(n: number, cb: (err?: any, result?: string[]) => void): void;
type Ret3 = typeof f2(number); // Promise<string[]>
type Ret4 = typeof f2(number, any); // void
type Ret5 = typeof f2(number, Function); // ERROR: Function not assignable to callback
type Ret6 = typeof f2(number, (err: any, result: string[]) => void); // void
type Ret7 = typeof f2(number, (...args) => any); // void
// A special function-like object
interface Receiver {
(data: string[]): void;
transmogrify(): number[];
}
declare function f3(n: number, receiver: Receiver): Promise<void>;
declare function f3(n: number, callback: (err?: any, result?: string[]) => void): void;
type Ret8 = typeof f3(number, Receiver); // Promise<void>
type Ret9 = typeof f3(number, any); // picks first overload
type Ret10 = typeof f3(number, Function); // ERROR
type Ret11 = typeof f3(number, (...args) => any); // void since not assignable to Receiver
// A function with parameter destructuring
interface CartesianCoordinate {/***/}
interface PolarCoordinate {/***/}
declare function f4({ x: number, y: number }): CartesianCoordinate;
declare function f4({ r: number, t: number }): PolarCoordinate;
type Ret12 = typeof f4(any); // picks first overload
type Ret13 = typeof f4({x;y}); // CartesianCoordinate
type Ret14 = typeof f4({r;t}); // PolarCoordinate
type Ret15 = typeof f4({x;r;t;y}); // picks first overload
// Type-ception: is there anything wrong with typeof-in-typeof?
declare function f5(n: number, receiver: Receiver): Promise<void>;
declare function f5(n: number, callback: (err?: any, result?: string[]) => void): void;
function myCallback(err, result) {/***/}
var myReceiver: Receiver;
type Ret16 = typeof f5(number, typeof myReceiver); // Promise<void>
type Ret17 = typeof f5(number, typeof myCallback); // void
ããã§äœãèµ·ããã®ãèå³ããããŸãïŒ
const number = "number";
type Ret3 = typeof f2(number); // What happens here?
@SaschaNazè¯ã質åã§ãã åæ§ã®ç¶æ³ïŒ
class MyClass { foo; bar; }
declare function f(inst: MyClass): number;
type Ret = typeof f(MyClass); // number (presumably)
ãã®å Žåã typeof f(MyClass)
ã§MyClass
_type_ãMyClass
_value_ïŒã€ãŸãã³ã³ã¹ãã©ã¯ã¿ãŒé¢æ°ïŒã®åã«èæ
®ããããšã¯çã«ããªã£ãŠããŸãã åè
ã¯Ret = number
ã«ã€ãªãããåŸè
ã¯error: MyClass is not a type
ã®ãããªãã®ã«ãªããŸãã
_type_ãš_constvalue_ã®äž¡æ¹ãåç
§ããååã«ãåãããžãã¯ãé©çšãããŸããïŒ ããªãã®äŸã§ã¯ãã¿ã€ãnumber
ãåžžã«constå€number
ãããåªå
ãããããšãæå³ããŸãã @RyanCavanaughã«ã€ããŠäœãèãã¯ãããŸããïŒ
ããã§ããããã¯ååŒã®éåžžã®ã»ãã³ãã£ã¯ã¹ã®äžã§è§£æ±ºãããŸãïŒ var x: [whatever]
ãèšè¿°ãããã®ããã«ïŒã ãããã£ãŠã typeof f(MyClass)
ã¯ã€ã³ã¹ã¿ã³ã¹åŽã§ã®f
ã®åŒã³åºããåç
§ãã typeof f(typeof MyClass)
ã¯ã³ã³ã¹ãã©ã¯ã¿ãŒé¢æ°ã§ã®f
ã®åŒã³åºããåç
§ããããšãã§ããŸãã
ã§ã¯ã @ SaschaNazã®äŸã§ã¯ã number
ã_const value_ã§ã¯ãªãã_type_ãšããŠæ確ã«åç
§ããŠããŸããã
const number = "number";
type Ret3 = typeof f2(number); // Promise<string[]>
@RyanCavanaughã¯ããŠãŒã¹ã±ãŒã¹ã®3çªç®ã®ã°ã«ãŒããç¯å²å€ã§ããããšã確èªã§ããŸããïŒ äŸïŒOPããïŒ
// Declare an interface DRY-ly and without introducing extra type names
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
// prop2 shares some structure with prop1
prop2: typeof (<MyInterface>null).prop1.big.complex; // OK: prop2 type is {anonymous: {type: {}}}
}
ãã®ãŠãŒã¹ã±ãŒã¹ïŒæ§æã¯åããªãïŒã¯ãçŸæç¹ã§ã¯ãµããŒããããŠããŸãããã
this
åŒãèš±å¯ããããšã§ããããã«ããŒããå¿
èŠããããŸãã
prop2: typeof this.prop1.big.complex;
const
ã¯ãå¥ã®typeof
ã§è§£æ±ºããå¿
èŠããããšæããŸãã
type Ret3 = typeof f2(typeof number); // typeof number is string so error here
...ããã¯typeof data[LOBOUND]
ããããã¯ããŸããã
@mhegazyããã¯typeof this
ã«é¢ããŠçŽ æŽãããã¢ã€ãã¢ã§ãã ç§ã¯ãããããã®ææ¡ã®ããã«äœæãããã©ãŒã¯ãããå®è£
ã§ãã§ã«æ©èœããŠããããšã«æ°ã¥ããŸããã ãŸããããã¯ã¯ã©ã¹ã®ããã«åããŸãã ã€ã³ã¿ãŒãã§ã€ã¹ã®å Žåããšã©ãŒã¯çºçããŸãããã this
ã¿ã€ãã¯åžžã«any
ãšããŠæšæž¬ãããŸãã ãã©ãŒã¯ãããimplããã®çŸåšã®åºåïŒ
class MyClass {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
};
prop2: typeof this.prop1.big.complex; // prop2 type is {anonymous: {type: {}}}
}
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
};
prop2: typeof this.prop1.big.complex; // prop2 type is any
}
ã€ã³ã¿ãŒãã§ã€ã¹å®£èšå
this
ãæšæž¬ããå¯èœæ§ã¯ãããŸããããããšããã®æ©èœã¯ã¯ã©ã¹ã«éå®ããããŸãŸã§ããïŒ
ïŒ6179ãšAngularã«ã€ããŠ2ã€ã®ãã€ã³ããè¿°ã¹ãããšæããŸãã
// A factory function that returns an instance of a local class
function myAPIFactory($http: HttpSvc, id: number) {
class MyAPI {
constructor(token: string) {...}
foo() {...}
bar() {...}
static id = id;
}
return MyAPI;
}
type MyAPIConstructor = typeof myAPIFactory(null, 0); // OK: MyAPI is myAPIFactory's return type
function augmentAPI(api: MyAPIConstructor) {...} // OK
ãã©ã¡ãŒã¿ã®æ°ã¯å€ããªãå¯èœæ§ããããŸãã 15åã®ãã©ã¡ãŒã¿ãèããŠã¿ãŸãããã åæã«ããªãŒããŒããŒãã¯ãªãã typeof
ã®ãã©ã¡ãŒã¿ãŒãå¿
èŠãªã®ã¯ãªãŒããŒããŒãã ãã§ãã ãããã£ãŠããã®å Žåããããã次ã®ãããªæ§æãèããããšãã§ããŸããïŒ
type MyAPI = typeof myAPIFactory(...);
éåžžããã¡ã¯ããªé¢æ°ã¯ç¬èªã®ã°ããŒãã«å€æ°ã«å²ãåœãŠãããŸããã é¢æ°åŒã䜿çšãããŸãïŒ
angular.module('app').factory('MyAPI', function($http: HttpSvc, id: number) { /*...*/ });
ããã¯éåžžãããã©ã®ããã«èŠãããã§ãã ã芧ã®ãšãããããã§ã¯typeof
ã¯ãŸã£ãã䜿çšã§ããŸããã
@ thron0ç§ã®çŽæã§ã¯ããã©ã¡ãŒã¿ãããã€ãããããå¿ååãè¿ããã®ã¯éåžžã«ãŸãã§ãã ã©ãæããŸããïŒ
Angular 1ãã¬ã¢ã«ãªããšããã以åã§ã¯ãªããã¬ã¢ã«ãªããŸãã
åºæ¬çã«ãããªãã説æããã®ã¯ãå žåçãªAngular_factory_ã§ãã
ããã€ãã®ãã©ã¡ãŒã¿ãæã£ãŠããããå¿åã¿ã€ããè¿ããã®
ããã¯ãäŸåé¢ä¿ããã©ã¡ãŒã¿ãŒãšããŠåãåãã_service_ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããé¢æ°ã§ãã å€æ°ã®ãã©ã¡ãŒã¿ãŒãé¢åã«ãªãå¯èœæ§ããããšèãããããããŸããããåé¡ã¯ããããã®ãã¡ã¯ããªãçŽæ¥åŒã³åºãããããšã¯ãªããšããããšã§ãã DIã³ã³ããã¯ããããåŒã³åºããŸãã ãã¡ã¯ããªã¯ãäŸåé¢ä¿ãšããŠæ»ãå€ïŒãµãŒãã¹ïŒãå¿ èŠãªå Žåã«åŒã³åºãããŸãã ãŸããAngularã§ã¯ãµãŒãã¹ã¯åžžã«ã·ã³ã°ã«ãã³ã§ãããããäžåºŠã ãåŒã³åºãããŸãã ãã ãããµãŒãã¹ã¯äœã§ãããŸããŸããããããã£ãŠãã·ã³ã°ã«ãã³ä»¥å€ã®åäœãå¿ èŠãªå Žåããã¡ã¯ããªã¯ã³ã³ã¹ãã©ã¯ã¿ãŒïŒãŸãã¯ãã¡ã¯ããªé¢æ°ïŒãè¿ãããšãã§ããŸãã ãã®ã³ãŒãäŸã®ããã«ïŒ
angular.module('app').factory('MyAPI', function($http: HttpSvc, id: number) {
class MyAPI {
constructor(token: string) {...}
foo() {...}
bar() {...}
static id = id;
}
return MyAPI;
});
ãã®ç¶æ³ã«å¯Ÿããç§ã®çŸåšã®åé¿çã¯æ¬¡ã®ããã«ãªããŸãã
class MyAPI {
// dependencies (1)
protected $http: HttpSvc;
protected id: number;
constructor(token: string) {...}
foo() {...}
bar() {...}
// Static properties cannot be used with this approach because:
// 1) this class is a global variable so it can be shared by different
// instances of the DI container,
// 2) the id property isn't available here as it's initialized in the subclass
//// static id0 = id;
}
angular.module('app').factory('MyAPI', function($http: HttpSvc, id: number) { // (2)
return class extends MyAPI {
$http = $http; // (3)
id = id;
};
});
// this type is needed for type annotations in the services that require MyAPI as a dependency
type MyAPIConstructor = typeof MyAPI;
angular.module('app').factory('someOtherService', function(MyAPI: MyAPIConstructor) {
var api = new MyAPI('qwerty');
/* ... */
});
ã芧ã®ãšãããããã¯å®å šã«éããŠèŠçã§ãã äŸåé¢ä¿ã3åãªã¹ãããå¿ èŠããããŸãã ããå€ãã®äŸåé¢ä¿ãããå Žåã¯ãéåžžã®æ¹æ³ïŒãã¡ã¯ããªé¢æ°å ïŒã§ã¯ã©ã¹ãèšè¿°ãããã®ã³ã³ã·ã¥ãŒããŒã®ã€ã³ã¿ãŒãã§ãŒã¹ã宣èšããæ¹ãç°¡åãªå ŽåããããŸãã
ããã«ã¡ã¯ãæ§æ/ã»ãã³ãã£ã¯ã¹ã®ã¿ã€ãããã®ãŸãŸã«ããŠã代ããã«åçŽãªã¿ã€ãã¢ã¯ã»ã¹ä»£æ°ãå®è£ ããããšãææ¡ããããšæããŸãã
ã¿ã€ãæ§æã®æ¡åŒµãæ³åããŠã¿ãŸãããã
type ::= ... | literalType | type typeAccess | guarded
guarded ::= "type" id
literalType ::= stringLiteral | numberLiteral | symLiteral | booleanLiteral
typeAccess ::= typeField | typeSubscript | typeCall
typeField ::= "." id
typeSubscript ::= "[" type "]"
typeCall ::= "(" [type {"," type}] ")"
ã¹ã³ãŒãå ã®åèå¥åã¯ã2ã€ã®ãšã³ãã£ãã£ã«åæã«ãã€ã³ãã§ããŸãã
ã¿ã€ãã¬ãŒãã¯åè ã®ã¿ãæœåºããŸãã ãããã£ãŠ
class A {}
var a: A;
ãšåçã§ã
class A {}
var a: type A;
ãã®å Žåãã¯ã©ã¹ãããã°
class ABC {
a: number;
b(x: number): string;
c:string[];
d:[number, string];
}
ãã®åŸãç§ãã¡ã¯æžãããšãã§ããŸã
var a: (type ABC).a; // number
var b: (type ABC).b(number); // string
var c: (type ABC).c[number]; // string
var d: (type ABC).c[0]; // number
ãŸããåå¥ã¹ã³ãŒãå ã®åãèå¥åã®äžã«ãã_type_ãšã³ãã£ãã£ãš_value_ãšã³ãã£ãã£ã®ããŒãžã«ã€ããŠã説æããŸãã
interface SAME {
x: number;
}
namespace SAME: {
export type x = boolean;
export var x: string;
}
var a: SAME.x // boolean
var b: (type SAME).x // number
var b: (typeof SAME).x // string
@ RyanCavanaugh ã @ sandersnãã®ã¢ã€ãã¢ãæ€èšã§ããŸããïŒ
ææ¡ã§è¡šçŸã®ã¿ã€ããã©ã®ããã«æããŸããïŒ
2016幎5æ19æ¥æšææ¥12:26AnatolyRessinã notifications @github.comã¯æ¬¡ã®ããã«æžããŠããŸãã
ããã«ã¡ã¯ãæ§æ/ã»ãã³ãã£ã¯ã¹ã®ã¿ã€ãããã®ãŸãŸã«ããŠã
代ããã«ãåçŽãªã¿ã€ãã®ã¢ã¯ã»ã¹ä»£æ°ãå®è£ ããŸããã¿ã€ãæ§æã®æ¡åŒµãæ³åããŠã¿ãŸãããã
ã¿ã€ã::=... | literalType | ã¿ã€ãtypeAccess| å®ããã
ä¿è·ããã::="type" id
literalType :: = stringLiteral | numberLiteral | symLiteral | booleanLiteral
typeAccess :: = typeField | typeSubscript | typeCall
typeField ::="ã" id
typeSubscript :: = "[" type "]"
typeCall :: = "ïŒ" [type {"ã" type}] "ïŒ"ã¹ã³ãŒãå ã®åèå¥åã¯ã2ã€ã«åæã«ãã€ã³ãã§ããŸã
ãšã³ãã£ãã£ïŒ
- ã³ã³ãã€ã«æã®ã¿ã€ã
- å®è¡æã®å€
_type_ã¬ãŒãã¯åè ã®ã¿ãæœåºããŸãã ãããã£ãŠ
ã¯ã©ã¹A{}
aïŒAãšåçã§ã
ã¯ã©ã¹A{}
aïŒã¿ã€ãAãã®å Žåãã¯ã©ã¹ãããã°
ã¯ã©ã¹ABC{
æ°;
bïŒxïŒæ°å€ïŒïŒæåå;
cïŒstring [];
dïŒ[æ°å€ãæåå];
}ãã®åŸãç§ãã¡ã¯æžãããšãã§ããŸã
var a :(ã¿ã€ãABCïŒ.a; // numbervar bïŒïŒtype ABCïŒ.bïŒnumberïŒ; // stringvar cïŒïŒtype ABCïŒ.c [number]; // stringvar d :(ã¿ã€ãABCïŒ.c [0]; // çªå·
ãŸãã_type_ãšã³ãã£ãã£ãš_value_ãšã³ãã£ãã£ã
åå¥ã¹ã³ãŒãå ã®åãèå¥åãã€ã³ã¿ãŒãã§ã€ã¹SAME{
xïŒæ°;
}åå空éåãïŒ{
ãšã¯ã¹ããŒãã¿ã€ãx=ããŒã«å€;
ãšã¯ã¹ããŒãå€æ°xïŒæåå;
}
var aïŒSAME.x // booleanvar bïŒïŒtype SAMEïŒ.x // numbervar bïŒïŒtypeof SAMEïŒ.x//æåå@RyanCavanaugh https://github.com/RyanCavanaughã@ sandersn
https://github.com/sandersnãã®ã¢ã€ãã¢ãæ€èšã§ããŸããïŒâ
ãã®ã¹ã¬ããã«ãµãã¹ã¯ã©ã€ãããŠããããããããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/Microsoft/TypeScript/issues/6606#issuecomment -220378019
ããªãã®äŸã¯ãç¹ç·ã®åŒã®ã¿ã€ããšã¿ã€ãããããã£ã¿ã€ãïŒ1295ãéåžžã«äŒŒãææ¡ã§ããããšãæãåºãããŸãã äžæ¹ãããéçã§ãããäžæ¹ãããåçã§ããããšãé€ããŠã
typeofããŒã¯ãŒããã¹ããããããšããã¢ã€ãã¢ã奜ãã§ãã
prop2: this.prop1.big.complex;
ããªãã®äŸã§ã¯@mhegazyãthis-expression
ã§typeof
ã䜿çšããŠããŸãïŒ
prop2: typeof this.prop1.big.complex;
ä»æ¥ãããè¡ãããšãã§ããã®ã§ïŒ
someProp: this;
ç§ã®èŠè§£ã§ã¯ãç¹ç·ã®ããããã£ãå¢ããããã®äžèšã®æ§æã®å€æ¿ã¯æ¬¡ã®ãšããã§ãã
someProp: this.prop1.prop2.prop3;
ãããŠããã§ã¯ãããŸããïŒ
someProp: typeof this.prop1.prop2.prop3;
ãããŠãå€æ¿ãç¶ããããã«â typeofããã¹ãŠäžç·ã«ã¹ãããããŠã¿ãŸãããïŒ
someProps: foo(number)
typeofãäžç·ã«ã¹ãããããŠã¿ãŸãããïŒ
ç§ãèããããšãã§ããçç±ã®1ã€ã¯ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹åŽãåç §ããŠããã®ããéçåŽãåç §ããŠããã®ãããããŸãã«ãªãããšã§ãã
class C {}
// Does 'x' have the instance type of 'C',
// or does it have the shape of its constructor?
let x: C;
å¥ã®ã€ã³ã¿ãŒãã§ãŒã¹å ã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ããããã£ã®ã¿ã€ããåç §ããããšæããŸãã ç§ã®äŸãïŒ10588ãšããŠæçš¿ããŸãããããã®ãã±ããã®ããã«çŸåšã¯ééãããŠããŸãã
ãã®ãããªãã®ãæžããšããã§ãããïŒ
interface Foo {
bar: string;
}
interface Box<T> {
container: T;
}
interface FooWithBoxedProps {
bar: Box<Foo.bar>; // OR: bar: Box<typeof Foo.bar>;
}
ããã¯åã«ããã«å€æãããŸãïŒ
interface Foo {
bar: string;
}
interface Box<T> {
container: T;
}
interface FooWithBoxedProps {
bar: Box<string>;
}
åè¿°ã®ã·ããªãªã®ããã€ãã¯ã_ã€ã³ããã¯ã¹ä»ãã¢ã¯ã»ã¹ã¿ã€ã_ïŒïŒ11929ïŒã§è¡šçŸã§ããããã«ãªããŸããã ãã®æ©èœãæšæºã®typeof
åŒãšçµã¿åãããã ãã§ã次ã®ããã«ãªããŸãã
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
// prop2 shares some structure with prop1
prop2: MyInterface["prop1"]["big"]["complex"];
}
ãããŠããã¯åäœããŸãïŒ ïŒçŸåštypescript @ nextã«ãããŸãïŒ
次ã®èªç¶ãªããšã¯äŒŒããããªãã®ã«ãªããšæããŸãããé¢æ°ã®å Žåã次ã®ãããªããã€ãã®ãé¢æ°åŒã³åºãã¿ã€ããããããŸãã
interface FunctionLike{
(arg1 : number, arg2 : string) : {a : number; b : string;}
}
type ReturnType = FunctionLike(number, string); // {a : number; b : string;}
ãããã£ãŠã typeof
æŒç®åãšèªç¶ã«çµã¿åãããããšãã§ããŸã
interface BigThing {
testString: string;
testNumber: number;
testBoolean: boolean;
}
function getSmallThing(thing:BigThing){
return {
testString : thing.testString,
testBoolean : thing.testBoolean
}
}
type SmallThing = typeof getSmallThing(BigThing) // {testString: string; testBoolean : boolean}
ãããŠãããã¯ãã®ã¹ã¬ããïŒ@tinganhoïŒã®åé ã§ãã§ã«ææ¡ãããŠããæ§æã®ããã§ãã :)
ãã ããçŸåšã®_ã€ã³ããã¯ã¹ä»ãã¢ã¯ã»ã¹ã¿ã€ã_ãšåæ§ã«ãçŸåšã®typeof
æŒç®åã䜿çšããŠé©åã«æ§æããæ¹ãããäžè¬çãªæ©èœã«ãªããŸãã
ãã ããããã€ãã®è³ªå/çåãæ®ã£ãŠããŸãã
typeofreturn
ãŸãã¯returnof
ïŒããã¯æè¡çã«å®çŸå¯èœã®ããã§ãã åŒæ°ã解決ããå¿ èŠããªãããã«ããªãŒããŒããŒã解決/ååŒæ°æšè«ã®ãªãã¡ã¯ã¿ãªã³ã°ãå¿ èŠã«ãªãå ŽåããããŸãã ãžã§ããªãã¯ã¹ãè¿œå ã®åé¡ãããŸãåŒãèµ·ãããªããšæããŸãã 質åã®1ã€ã¯ãåŒã³åºãã«äžèŽãããªãŒããŒããŒãããªãå Žåã«ã©ããªããã§ãã
ãã®æ©èœãæãŸãããã©ããã¯æããã§ã¯ãªããšæããŸãã é¢æ°ãéåžžã«è€éãªå¿ååãè¿ãå Žåããã®ããã«åç §ããå¿ èŠããªãããã«ãåã«ååãä»ããããšã¯äœæè ãšããŠãã圹ç«ã€ã®ã§ã¯ãªãã§ããããã ç§ã¯ãããåã«æäœã®å¥œã¿ã«åºã¥ããŠããããšãèªããŸãã ãããå®éã«ã©ãã»ã©äŸ¿å©ãããããªããšæããŸãã ãã ããèŠçŽ ã¢ã¯ã»ã¹ã«ã¯åé¡ãªããšæããŸãã
ã¿ã€ãP=typeof fooïŒ0ïŒ; //Pã¯any[]
ã¿ã€ãQ=typeof fooïŒtrueïŒ; //Qã¯æååã§ã
ãã©ã¡ãŒã¿ããã®ã¿ã€ãã§åç
§ã§ããããã«ããããšã«ã€ããŠã®ãã®è°è«ã§ã¯ãå®éã®é¢æ°ã«ãåãããšãèš±å¯ããããšããå§ãããŸãã
ã³ã³ããã¹ãïŒãªããžã§ã¯ãã«å¯ŸããŠmap
ã«é¢æ°ãå
¥åãããïŒ
function map<T, F extends Function>(fn: F, obj: T): { [P in keyof T]: typeof F(T[P]) }
é¢æ°ããã®ã¿ã€ãF
ïŒååfn
ã ãã§ãªãïŒã§åç
§ã§ããããã«ãããçç±ã¯ããã®ååã䜿çšã§ããªãå¯èœæ§ãããå Žåã§ãã d type MapFn<T, F extends Function> = { [P in keyof T]: typeof F(T[P]) }
ãšèšããããã«ãããã
ããããå®è£ ãã¯ããã«ç°¡åã§ããïŒãããŠããã§ãéåžžã«åœ¹ç«ã€ïŒãã®ã¯æ¬¡ã®ããã«ãªããŸãã
const myFunc = () => ({ x: 10 });
type myType = returnof myFunc; // { x: number; }
çè«çã«ã¯ãã¿ã€ããæ°ã¬ãã«æ·±ããããå Žåã¯ãããããé£éãããããšãã§ããŸãã äœããæèŠã¯ïŒ
ç·šéïŒããã@mpawelskiã«ãã£ãŠäžã§èšåãããããšã«æ°ã¥ããŸããð
@dehliãã ãããªãŒããŒããŒããããé¢æ°ã§ã¯æ©èœããŸããã ãŸãã¯ãæ»ãåã§åãã©ã¡ãŒã¿ãŒã䜿çšããããžã§ããªãã¯é¢æ°ã
@JsonFreemanããŸããŸãªãªã¿ãŒã³ã¿ã€ãã ãã§é¢æ°ããªãŒããŒããŒãã§ããŸããOR
ããïŒ ãããŠç·ç§°é¢æ°ã¯ããªããã¿ã€ããæå®ããããšãèŠæ±ãããããããŸãããïŒ
ããã¯å¯èœã§ããããããã©ãã»ã©åœ¹ç«ã€ãã¯ããããŸããã 人ã ã¯ãã£ãšæŽç·Žããããã®ãæãã§ããããã§ãã
æ¬åœã«èŠçãªã®ã§ããããããã«å®è£ ãããããšãæ¬åœã«æãã§ããŸãã
æåŸã®åé¿çã¯ããæ©èœããªãã®ã§ãç§ã¯çŸåšããã䜿çšããŠããŸãïŒ
// 0 argument function
export default function returnof<T>(fn: () => T): T;
// 1 argument function
// If no ambiguity simply infer the return type
export default function returnof<A, T>(fn: (a: A) => T): T;
// 1 argument function, with possible overload for the argument type.
// Explicitly set the type and use the correct overload
export default function returnof<A, T>(fn: (a: A) => T, a: A): T;
// ...
é¢æ°ã®ãªãŒããŒããŒãããªãå Žåã¯ãåŒæ°ãæå®ããå¿ èŠã¯ãããŸããã
const hello = (arg: number) => 'World'
const helloReturnValue = returnof(hello)
type helloReturnType = typeof helloReturnValue // string
declare function hello(): void;
declare function hello(a: number): number;
const helloReturnValue = returnof(hello)
type helloReturnType = typeof helloReturnValue // void
const helloReturnValue = returnof(hello, 42)
type helloReturnType = typeof helloReturnValue // number
ãã¹ãŠã®å®çŸ©ã¯ããã«ãããŸãïŒ
https://github.com/kube/returnof/blob/master/lib/returnof.d.ts
ãããžã§ã¯ããæ±æããããšãªãç°¡åã«ãã³ãã«ã§ããããã«ãå°ããªNPMããã±ãŒãžãäœæããŸããã
https://github.com/Microsoft/TypeScript/issues/2175ã§ææ¡ãããŠããããã«ãªãã·ã§ã³ã®ãžã§ããªãã¯ã¹ãè¿œå ãããå ŽåãåçŽãªå®£èšåã®ã¿ã®åé¿çãå¯èœã«ãªããŸãã
type Return<T extends () => S, S> = S
ãããŠã次ã®ããã«äœ¿çšããŸãã
type helloReturnType = Return<typeof hello>
@mhegazy @JsonFreemanãã®æ©èœã«é¢ããèšç»ã¯ãããŸããïŒ
çããããã«ã¡ã¯ã
ç§ã¯ãã®åé¡ã«å¯Ÿãã代æ¿ã®å¯èœãªè§£æ±ºçãæã£ãŠããŸãïŒããããã§ã«ææ¡ãããŠããŠãç§ããããéããå Žåã¯ç³ãèš³ãããŸããïŒ-ç§ã¯åé¡ïŒ13949ã§ãããææ¡ããŸããã ãã®æ®µéã§ã¯æŒç®åã®çš®é¡ã«ã€ããŠã¯ç¥ããŸããã§ããããç§ã®è§£æ±ºçã¯ãã£ãšäžè¬çã ãšæããŸãã åºæ¬çã«ã =MyType
ã®ãããªæ°ããæ§æãå°å
¥ããŸããããã¯ã MyType
ã䜿çšããå Žæãªãã©ãã§ã䜿çšã§ããŸããããªããžã§ã¯ããMyType
åã§ãããšå®£èšãã代ããã«ããªããžã§ã¯ãã®æšæž¬ãããåããMyType
ãšããååã®åã ããšãã°ãããã¯Vueã³ã³ããŒãã³ãã®äœæã«äœ¿çšããæ¹æ³ã§ãã
function createData(){
return <=MyData>{
dataProp1: <string>null
}
}
function method1(){
let self: MyComponent = this;
console.log(self.dataProp1);
self.method2();
}
function method2(){
let self: MyComponent = this;
//dostuff
}
type MyComponent = MyData & MyMethods;
let componentOptions = {
data: createData,
methods: <=MyMethods>{method1, method2}
}
//todo: register component...
createData
é¢æ°ã¯æ¬¡ã®ããã«æžãããšãã§ããŸãã
function createData(): =MyData {
return {
dataProp1: <string>null
}
}
ç§ã¯ãããããè¡šçŸã«äžè¬åããæ¬åœã«æ¥œããåé¿çãèŠã€ããŸããïŒ
const varWithRightType = (false as true) && some.deep.access()
type MyType = typeof varWithRightType;
ç·šéïŒç§ã«ç¬ãã®ããããªããããã¯æ·±å»ãªã¿ã€ãã¹ã¯ãªããã§ã
@johnfnããã¯åçŽãªã±ãŒã¹ã§ã¯é¢çœããã§ã:)ããé¢æ°ã«ããã€ãã®ãã©ã¡ãŒã¿ãå¿ èŠãªå Žåã¯ã次ã®ããã«è¿œå ã®åé¿çãè¬ããå¿ èŠããããŸãã
const stateProps = (false as true) && mapStateToProps({} as any);
ç§ã¯å¥ã®åé¿çã䜿çšããŠããŸããããã¯ãåæšè«ã䜿çšããŠmapStateToProps
é¢æ°ããå°éå
·ã®åãååŸããããšãããšãã«ReactãšReduxã§ç¹ã«åœ¹ç«ã¡ãŸãã ããããã°ãRedux connect
ã«ãã£ãŠæ³šå
¥ãããããããã®ã€ã³ã¿ãŒãã§ãŒã¹ãæåã§å®£èšããŠç¶æããå¿
èŠããªããªããŸããããã¯ç¶æãé¢åã§ãšã©ãŒãçºçãããããªããŸãã
ãã®åé¿çã¯ãä»ã®ãŠãŒã¹ã±ãŒã¹ã®ç¹å®ã®é¢æ°ã·ã°ããã£ãé©åã«åŠçããŸãã
typeof
æŒç®åãReactïŒReduxãã®ãŠãŒã¹ã±ãŒã¹ã®äŸïŒ
以äžã®äŸã§ã¯ã
typeof
æŒç®åã䜿çšããŠãTypeScriptã«è¿œå ãããšéåžžã«åœ¹ç«ã€é¢æ°å®£èšããåãå°åºããããã®ãäžè¬çãªå®éã®ãããžã§ã¯ãã®ãŠãŒã¹ã±ãŒã¹ã瀺ããŸãã
import { returntypeof } from 'react-redux-typescript';
import { RootState } from '../../store';
...
const mapStateToProps = (state: RootState) => ({
currencies: CurrencyRatesSelectors.getCurrencies(state),
currencyConverter: storeState.currencyConverter,
});
const stateProps = returntypeof(mapStateToProps);
type Props = typeof stateProps & typeof dispatchToProps;
type State = {};
class CurrencyConverterContainer extends React.Component<Props, State> {
...
ãœãŒã¹ïŒ https ïŒ//github.com/piotrwitek/react-redux-typescript-patterns#react -connected-components
@kubeã®ãœãªã¥ãŒã·ã§ã³ãšãã®ããã±ãŒãžhttps://github.com/kube/returnofã¯æåŸ ã©ããã«æ©èœããŠããããã§ãïŒ ð
ããŒãã returnof
ã.d.ts
ãã¡ã€ã«ããã¿ãã«ããŒã¹ã®map()
ãå
¥åããã®ã«åœ¹ç«ã€ããšãæã¿ãŸãããåŒèšèªã«äŸåããŠããããïŒ const
ã¯ã¢ã³ããšã³ãã³ã³ããã¹ãã§ã¯äœ¿çšã§ããŸããïŒ ïŒãç§ã¯ããã䜿ã£ãç§ã®ãŠãŒã¹ã±ãŒã¹ãå°ãªããšããã£ãšè€éã«ãªãã®ã§ã¯ãªãããšå¿é
ããŠããŸãã
ç·šéïŒãªãã·ã§ã³ã®ãžã§ããªãã¯ãä»ã§ã¯ããŒãžãããŠããããã§ããã€ãŸãã @ kubeã®å®£èšåèšèªã®ã¿ã®ããŒãžã§ã³ïŒ type Return<T extends () => S, S> = S
-> type helloReturnType = Return<typeof hello>
ïŒãå®è¡å¯èœã«ãªããŸãã ïŒD
èšæ£ïŒããããããã©ã«ãã®ãžã§ããªãã¯å€ã®ããŒãžããããµããŒãã§ã¯ããžã§ããªãã¯ã®äžéšãæå®ããããšã¯ã§ããŸããããä»ã®äººã¯æšæž¬ãããå€ã«ãã©ãŒã«ããã¯ã§ããŸãã Return<typeof hello>
ã¯ãšã©ãŒGeneric type 'Return' requires 2 type argument(s).
ãçæããŸãã
@tycho01ãããããåé¡ã解決ããªãã£ãããšã«ãã£ããããã
ãªãã·ã§ã³ã®ãžã§ããªãã¯åæšè«ã«é¢ããé¢é£ããåé¡ããã§ã«éããŠããŸãïŒ
éåžžããããŒã®ã¢ã³ããšã³ãé¢æ°ãšåæšè«ãçµã¿åãããŠãé¢æ°ã®æ»ãåãååŸã§ããŸãã
ã¢ã³ããšã³ãfunction returnTypeOf<RT>(fn:(...rest:any[])=>RT):RT {return void 0};
ããŒã«ã«ã§var r = returnTypeOf(someFunction);
ã¯å€undefined
$ãååŸããŸã
ãããããã®ãªã¿ãŒã³ã¿ã€ããåå©çšãããå Žåã¯ãããããã£ããã£ããå¿ èŠããããŸã...ããã§ãæåã®å Žæã«æ»ããŸãã
type RT = typeof r;
æåã«typeof
ã®æŠå¿µãæ¡åŒµããŠã returntypeof
$ãèš±å¯ãããã typeof fn(a,b,c,...)
ãããã®äœ¿çšæ³ãæšæž¬ããŠãããŸããŸãªçœ²åã®æ»ãã¿ã€ãããã£ããã£ã§ããããã«ãããšãã¯ããã«ç°¡åã«ãªããŸãã ã ãã®ãªã¿ãŒã³ã¿ã€ãã®ç解ã¯ãTSã«ãã£ãŠãã§ã«å
éšçã«å®è¡ãããŠããŸãã
typeofexpression ()
ã¯ãã¿ã€ãæäœãšæ··åãããäžçš®ã®ãªã¿ãŒã³ã¿ã€ãååž°ã«ãªããŸãã
type E = typeofexpression (f(1) + g("x"))
ã¯
type E = typecomprehensionof (typeof f(1) + typeof g("x"))
ã®ããã«ç解ããããããããŸãã
type E = typecomprehensionof (string + string)
ããªãã¡string
type E = typecomprehensionof (string + number)
ããªãã¡string
type E = typecomprehensionof (number + number)
ããªãã¡number
ãããå éšçã«ã©ãã»ã©é£ãããããããŠããã©ãŒãã³ã¹ã³ã¹ãã¯ç§ã«ã¯ããããŸããã
ç·šé - - - - - - - - - - - - - - - - - - - - - - - - - ------------
è¿œå ããã€ããã§ãã...ããã¯ãFunction.bindãFunction.applyãFunction.callã䜿çšããå¿
èŠããã人ã«ãšã£ãŠç¹ã«éèŠã§ãããããã¯çŸåšã¿ã€ãany
ãè¿ããããã¯åžžã«ã¿ã€ã-ã§ããå¿
èŠãããããšãæå³ããŸããã¿ã€ããã§ãã¯ããã»ã¹ããå€ããªãããã«æ³šéãä»ããããŠããŸãã
é¢æ°ã®åŒæ°ã®æ»ãåãåç §ã§ããããã«ãªããšã...è³çŠ...
@poseidonCore
é¢æ°ã®åŒæ°ã®æ»ãåãåç §ã§ããããã«ãªããšã...è³çŠ...
ç§ã¯çŸåšã®typeof <expression>
ã®æ¹ã奜ãã§ããªã¿ãŒã³ã¿ã€ãã®åé¡ã¯ãã§ã«ïŒ12342ã§ã«ããŒãããŠããŸãã
説æã§ãããã®äœ¿çšæ³ãåºå¥ããæ段ãšããŠã typeofexpression
ãštypecomprehensionof
ã䜿çšããŠããŸããã å®éã®æ§æãšããŠtypeof (expression)
ããå§ãããŸãã
ç§ã®ãã€ã³ãã¯ãåŒã®åãç解ããã«ã¯ãé¢æ°ã®æ»ãåãç解ããå¿
èŠããããšããããšã§ãã... f(1)
ãåŒã§ãã ïŒ12342ã¯ãã®ããã«é¢é£ããŠããŸãã ãããã¯çžäºã«æä»çã§ã¯ãããŸããã
å€æ°ã«å¯ŸããŠã¯ãã§ã«typeof
ãå®è¡ã§ããŸããåŒã¯å€æ°ãšé¢æ°ã«å¯ŸããæŒç®ã§ããããã次ã®èŠä»¶ã¯é¢æ°ã®åãè¿ãããšãã§ããããšã§ã...ãããŠåã®èŠåã«åºã¥ããŠçµæãç解ããããšã§ãã
å®ã¯è¯ãç¹ã§ãã ïŒ12342ãæãã§ããåé¡ã¯ããžã§ããªãã¯åã®ããããã£ã®ãããªãã®ãšããŠæ»ãåã«ã¢ã¯ã»ã¹ããæ¹æ³ã§ãããããé¢ä¿ã誀解ããŸããã
ææ¡ã®ããã«typeof
é¢æ°ã®åŒã³åºãã«åŒã䜿çšããŸããããã©ã¡ãŒã¿ãŒã®ä»£ããã«åãçŽæ¥äœ¿çšããã®ã¯ã©ãã§ããïŒ
äŸãã°
function myFunction<T>(param1: T, param2: string, param3: number): T & {test: string} {
// ...
}
type ResultType = typeof myFunction({hello: string}, string, number)
// ResultType is: {hello: string} & {test: string}
ããã¯ãåŒã³åºãå ã§typeofã䜿çšããããšã«ãããããŒã«ã«ã¹ã³ãŒãã®å€æ°ã®ã¿ã€ãã䜿çšããããšã劚ãããã®ã§ã¯ãªãããšã«æ³šæããŠãã ããã
type ResultType = typeof myFunction(typeof obj, string, number)
// ResultType is: typeof obj & {test: string}
ããã¯ãå ã®ææ¡ãããå°ãåªããŠããããã«èŠããŸããããã¯ãåšå²ã®ç¶æ³ã§æ©èœããäžè¬çã«æè»æ§ãé«ãããã«èŠããããã§ãã ãŸããå®éã«ã¯é¢æ°ãåŒã³åºããŠããããæ»ãå€ã®åãè¿ãããšããŠããã ãã§ããããšãæ確ã«ãªããŸãã
ç§ã®åçŽãªã±ãŒã¹ã§ãããã©ã®ããã«è¡ã£ããïŒ
interface IAlertMessage {
addedAt: number;
text: string;
type: "error" | "warning" | "info" | "success";
}
declare let alertMessageInterface: IAlertMessage;
const messages: IAlertMessage[] = [];
function addMessage(text: string, type: typeof alertMessageInterface.type): void {
messages.push({addedAt: new Date().getTime(), text, type});
}
addMessage("something", "info"); // <- OK - and also has intellisense for the second parameter (after typing first " of the second parameter, press Ctrl+Space in VSCode)
addMessage("something", "fatal"); // <- Compilation error : error TS2345: Argument of type '"fatal"' is not assignable to parameter of type '"error" | "warning" | "info" | "success"'.
äžèšã¯ãã€ã³ã¿ãŒãã§ãŒã¹èªäœã®ã¡ã³ããŒã§ãæ©èœããŸãã
declare let myIface: MyInterface;
interface MyInterface {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
prop2: typeof myIface.prop1.big.complex.anonymous;
}
type ...
declare let ...
ã䜿çšããå©ç¹ã¯ãåºå.jsãã¡ã€ã«ã«äœãçæãããªãããšã§ãã
@varaderoããã¯ãé¢æ°åŒã³åºãã®æ»ãåãååŸãããšããåœé¢ã®åé¡ã解決ããŸããã ããªããããŠããã®ã¯ãTypeScript 2.2以éã§ãµããŒããããŠããæ©èœã§ãããåã®ããããã£ã®åãååŸããããšã ãã ãšæããŸãã
ããã¯å®éã«ã¯ïŒåœã®ïŒå€ã®ããããã£ã®ã¿ã€ãã§ãã ã³ã³ãã€ã©ã§ã¯ãtypeofããçŽç²ãªãåãŸãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§äœ¿çšããããšã¯ã§ããŸãããå€ã«å¯ŸããŠã®ã¿æ©èœããŸãã
ããã¯çŽ æŽãããããšã§ãïŒ
type KEYOF<T extends any[]> = keyof T[0]
ãã§ã«ååšããããã function myFunc<T, K extends KEYOF<T>>(type: K)>{ }
ãšmyFunc([(r: string) => r])
ïŒ typeof T[0]('something')
ã®æååãè¿ãïŒãæ³å®ãããšã typeof T[0]('something')
ããã®å®è£
ã§æ©èœããŸãã ïŒ
ããã¯ãå€åœ¢ã®this
ãšäžç·ã«åŒ·åã«ãªããŸãã
ãããèµ·ããæéã§ãïŒ
ãã®ã¹ã¬ãããèªã¿çŽããŠã typeof
ã§äœãããŠããã®ãããããŠãã®çç±ãç解ããããšããŸããã
æããã«ããã§ã«å®è£
ãããŠããäºçŽ°ãªtypeof foo
ã®å Žåã foo
ã®ã¿ã€ãã«ãªããŸãã ïŒ pet is Fish
ã¯ãç¹å¥ãªæ§æã䜿çšããŠã圱é¿ãåããªããšæããŸããïŒ
ãã®ããŒã¯ãŒããçŸåšã®ææ¡ã§äœããã¹ããã«ã€ããŠã®ç§ã®çŸåšã®èªæžã§ã¯ãããŒã¯ãŒãèªäœã¯çŸåšã®ããšä»¥äžã®ããšã¯ãããçŸåšã®ææ¡ã¯å®éã«ã¯typeof
ããŒã¯ãŒããšã¯ç¡é¢ä¿ã§ãã
ããã¯ãåè¿°ã®å Žåãå€ãšããŠã§ã¯ãªããåïŒ type
ãŸãã¯ãžã§ããªãã¯ïŒãšããŠæ ŒçŽãããé¢æ°ãé©çšããå Žåã«éèŠã§ããããã§ãã
ãããèãããšã typeof fn<A>(string)
ã¯åã¬ãã«ã§äœ¿çšããããã«åŒã¬ãã«ã®å€æ°fn
typeof
$ãå¿
èŠã§ãããäžæ¹ã§Fn<A>(string)
ã¯ãé¢æ°ãå«ããžã§ããªãã¯ãšããŠFn
ã䜿çšãããšããããå¿
èŠãšããªãããã typeof
ãå¿
èŠãšããã«ãããã§é©åãªæ»ãåãååŸããããã«ãé©çšãã§ããŸãã
ãã®è§£éã§ã¯ãæœåšçãªé¢æ°åã®åŸã«é¢æ°åŒã³åºãããã§ãã¯ããŸãã typeof fn(...)
/ typeof fn<...>(...)
ã®ã»ãã«ã Fn(...)
/ Fn<...>(...)
ããé¢æ°ã§ãããªãå Žåã¯ãªãã©ã«((foo: Foo) => Bar)(Baz)
/+ãžã§ããªãã¯ã ãã以å€ã®å Žåãæ»æã®èšç»ã¯ãã®ãŸãŸã«ããŠããå¿
èŠããããŸãã
å€åç§ã¯ããªããã¡ããããã©ã®ããã«èŠãŠãããã誀解ããŠãããããããŸãããå€ååã«ä¿åãããé¢æ°ã¯ã¡ããã©èæ ®ãããŠããŸããã§ããïŒç§ã¯ãããã®èšåãèŠã€ããããªãã£ãã®ã§ïŒã ãããã«ããã確èªãã䟡å€ããããšæããŸããã
ãã ããé¢æ°é©çšã®ã¢ããŠã³ã¹ãtypeof
ã®ã»ãã³ãã£ãã¯ãªãŒããŒããŒãã«ãªãå Žåã¯ãã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã®ææ§æ§è§£æ¶ãšãåŒã¬ãã«ã®å€æ°ã®åã¬ãã«ãžã®åŒãäžãïŒåŒã¬ãã«ã®typeof
ãé€ãïŒã«å ããŠããã®ã¹ã¬ããã®ä»¥åã®ããã€ãã®è³ªåã§ãã§ã«ç€ºãããŠããããã«ãåŸã
ã«è€éã«ãªã£ãŠããããã«èŠããŸãã
ç·šéïŒãžã§ããªãã¯åã¯ãã§ã«é¢æ°åãè¿ãããšãã§ãããžã§ããªãã¯ãæã€ããšãã§ããŸãã ããã¯ãå¥ã®é åãGetFn<A><B>()
ã«ãªãããšãæå³ããæåã®ãžã§ããªãã¯ã»ããã¯ãžã§ããªãã¯åã®åŒã³åºãã«å±ããåŸè
ã¯é¢æ°ã®åŒã³åºãã«å±ããŸãã GetFn<A><B><C>()
ãããŸãããã GetFn<A><B>()<C>()
ãåæ³ã§ãã ãã ãã以åã®çµè«ã¯å€æŽãããŠããŸãããã©ã®ã¿ã€ãã«ãé¢æ°ãå«ããããšãã§ãããããïŒæœåšçã«ïŒé¢æ°ãšããŠé©çšãããŸãã
ç·šé2ïŒ X<Y>()
ã«äžå¹žãªãããŸãããååšããããšã«æ°ã¥ããŸããã ããã§ã X
ã¯é¢æ°åãè¿ãåã«ãªããŸãã
X
ãäžè¬çã§ãªãå Žåãããã¯æããã§ã- <Y>
ã¯é¢æ°åŒã³åºãã«å±ããŸããX
ãæ±çšã§ããããã©ã¡ãŒã¿ãŒãå¿
èŠãªå Žåããããæããã§ããããã¯åã«å±ããé¢æ°ã«ã¯åãã©ã¡ãŒã¿ãŒãæž¡ãããŸãããX
ã«ãªãã·ã§ã³ã®ãžã§ããªãã¯ãå«ãŸããŠããå Žåãããã¯ãããŸãã«ãªããŸããX
ã«ã¯åãã©ã¡ãŒã¿ãŒãæž¡ãããŸãããé¢æ°ã«ã¯æž¡ãããŸãããX
ã¯ããã©ã«ãã®åãã©ã¡ãŒã¿ãŒã䜿çšããããã«æ®ãããŸããã <Y>
ã¯ä»£ããã«é¢æ°åŒã³åºãããã©ã¡ãŒã¿ãŒåããŸããããã§æåã®è§£æ±ºçãäœã§ãããã¯ãŸã ããããŸããã
<>
ãæ瀺çã«äœ¿çšããããšã§ãã ãã ããããã¯é倧ãªå€æŽã«ãªããŸãã@icholy ïŒããããããã®ç·šéã¯ããªãã®ãã€ã³ããããã«è¿œå ããŠããã ãã§ããç§ã¯ç¥ã£ãŠããŸãã
ç·šé3ïŒããããŸããããã®æ©èœã¯ç§ã®ãŠã£ãã·ã¥ãªã¹ãã®äžçªäžã«ãããŸãã æšè«ãžã®åœ±é¿ãšããç¹ã§ãä»ã®ã¢ããã°ã¬ãŒãã¯ãªã¢ãŒãã§ããè¿ã¥ããŠããŸããã
@icholy ïŒèŠããã«ããé¢æ°ãããžã§ããªãã¯/ã¿ã€ãã«ããå Žåã§ãã typeof
ãšæžãã§ããããïŒ
ãããè¡ããããªãŒããŒããŒããšæ£ããçžäºäœçšããå Žåãé¢æ°ã®æ»ãåãååž°çã«å®çŸ©ã§ãããããå®éã«ã¯ç¡æã§ãå¯å€ååŒæ°ãé¢æ°ãæäŸãããŸãïŒ1ã€ä»¥äžã®ã¢ãªãã£ãæã€ä»£ããã«ã«ã¬ãŒãããŸãïŒããªãŒããŒããŒãã®1ã€ãé©çšããããŒã¹ã±ãŒã¹ã®ãªãŒããŒããŒããããã€ã䜿çšããŸãã ãããHaskellã§ã®ããæ¹ã§ãããTypeScriptã«ãããšçŽ æŽãããæ©èœã«ãªãã§ãããã
@masaeedu ïŒé¢çœããã§ããã ãããŠãããããªãŒããŒããŒãã¯ééããªããã®ææ¡ãéåžžã«èå³æ·±ããã®ã«ããŸã-ãããã¯ãããŸããŸãªãªãã·ã§ã³ã§ãã¿ãŒã³ãããã³ã°ãè¡ãããã«äœ¿çšã§ãã any
ãã©ãŒã«ããã¯ãå«ãŸããŠããŸãã ãããŸã§ã®ãšããããã®ãããªã¿ã€ããã§ãã¯ã¯ã¿ã€ãã¬ãã«ã§ã¯äžå¯èœã§ããã
HaskellãããRamdaãå€çšããããšãèªããŸãã ãããããã®èæ¯ãããã«ã¬ãŒã¯çµæãè¿ãããè¿œå ã®åŒæ°ãåŠçããå¥ã®é¢æ°ãè¿ããããç¥ããå¿ èŠããããããéåžžãã«ãªãŒåã¯å¯å€ååŒæ°é¢æ°ãšããŸãçµã¿åãããããªããšæããŸããã
Object.assign
ã®ãããªå¯å€ååŒæ°é¢æ°ã§ãã®ã¢ã€ãã¢ãã©ã®ããã«æ©èœãããã«ã€ããŠã®æ¬äŒŒã³ãŒãã瀺ããŠããã ããŸãããïŒ &
ãšOverwrite
ã®ãããªè©³çŽ°ãã¹ãããããŠäœ¿çšããŸããïŒç§ã®PoCã§R.mergeAll
ïŒïŒ
@ tycho01ç§ã¯ãã®ãããªã³ãŒãã§éãã§ããŸãïŒ
interface Pop<TVarStack extends VarStack> {
(a: TVarStack["head"]): Pop<TVarStack["tail"]>
}
interface VarStack<THead = any, TTail extends (void | VarStack) = any> {
head: THead
tail: TTail
<TNew>(a: TNew): VarStack<TNew, this>
(): (a: Pop<this>) => any
}
// Figure out implementation later :)
let stack: VarStack<void, void>;
const pop = stack(new Date())(10)("Bob's")("your")("uncle")()
// a, b, c, d, and e are well-typed
pop(a => b => c => d => e => {
// Need this because can't figure out how to encode base-case in Pop recursion
return stack
})
VarStack
ã¯ãããæå³ã§ãå¯å€ååŒæ°ãé¢æ°åã§ãããä»»æã®æ°ã®ç°çš®åŒæ°ãæå®ã§ããåã¬ãã«ã§ååž°ã䜿çšããŠé¢é£ããåæ
å ±ãå¿ å®ã«èšé²ããŸãã æ®å¿µãªãããTypeScriptã¯ãHaskellãšåãããã«ãåã¬ãã«ã§ã®å€æãšãã¿ãŒã³ãããã³ã°ãé©åã«ãµããŒãããŠããŸããã
typeof
ã«ã¢ã¯ã»ã¹ã§ããå Žåã returnof(overloadedFunction(T))
ã¯åºæ¬çã«ãã¿ãŒã³ãå®è¡ããæ¹æ³ãæäŸããããã Pop
ã®ããŒã¹ã±ãŒã¹ã®åé¡ã解決ã§ããŸããã¿ã€ãã¬ãã«ã§ã®ãããã³ã°ã
@ tycho01 Object.assign
ã§æ£ç¢ºã«å®è¡ããããšã¯ã§ããŸãããããã¯ãåè¿°ã®ããã«ãã«ã¬ãŒé¢æ°ã§ã®ã¿æ©èœããããã§ããã倧ãŸãã«æ©èœããã«ã¬ãŒassign
é¢æ°ãäœæããŠã¿ãŸããåãæ¹æ³ã
ããšãã°ã (a: string) => (b: number) => void
ãFunc<string, Func<number, void>>
ã®ç ç³ã§ããã (a: string, b: number) => void
ãArity<number, Arity<string, void>>
ã®ç ç³ã§ããããã«ãå代æ°ãå°ãäžè¬åããŠã»ãããšæããŸãããããªæãã 次ã«ãå€ãã®èå³æ·±ãæ©èœãç·æ¥ã«ååŸããããã«ãåãå€æããããã®æ±çšããŒã«ãå¿
èŠã«ãªããŸãã
ããªãã«ãã¹ãã«ã€ããŠãè©«ã³ç³ãäžããŸãã @tycho01ãããã«ã¬ãŒã®ãå¯å€ååŒæ°ã assign
ã§ãïŒ
interface Assign<TCurr extends {} = {}> {
<TAdd extends {}>(a: TAdd): Assign<TCurr & TAdd>
(): TCurr
}
let assign: Assign = undefined // implement somehow
const result = assign({ foo: "bar" })({ baz: 42 })()
@masaeedu ïŒãããšãããã¯ã¬ãã¥ãŒãµãŒé¢æ°ãæã£ãŠãããããªãã®ã ãšæããŸã:)ã§ãããå¯å€ååŒæ°ïŒïŒïŒä»¥å€ã®åŒæ°ããããšããã®éšåã¯ãã£ãšé£ãããªãå¯èœæ§ããããŸãã
ç§ã¯ãã®ã¢ã€ãã¢ã奜ãã§ãã ç§ã¯ééããªãã€ã³ã¿ãŒãã§ãŒã¹ã®æ¹åã«ã€ããŠããŸãèããŠããŸããã§ããã
ãã ããã¿ã€ãã³ã°ã®JSãå€æŽã§ããå Žåã¯ãTC39ã«Object.assign
ãéå¯å€ååŒæ°ã®mergeAll
ã«å€æŽããããã«äŸé ŒããŸãã ïŒD
ãããŸã§ã®ãšãããå®éã«é¢æ°ã§æ©èœããŠãããããªå¢åããŒã¹ã®å埩ãšã¯ç°ãªããŸãïŒïŒ17086ïŒ...ããããã©ã¡ãã«ããŠãããã®ææ¡ã¯ããããŸã§ã«èŠãã©ã®ææ¡ããã倧ããªåœ±é¿ãåãŒããŸãã
@ tycho01 JSïŒãŸãã¯å°ãªããšãæ¢åã®JSãšã³ãžã³ãšã³ãŒãïŒã®ã«ã¬ãŒé¢æ°ãŸãã¯ç¹°ãè¿ãé©çšã«ã¯å®è¡æã³ã¹ããããããããå¯å€ååŒæ°é¢æ°ãåºå®ã¢ãªãã£é¢æ°ã«å€æããããã«èŠæ±ããå Žåã倧ããªçœåŒåãåŸãå¯èœæ§ã¯äœããšæããŸããããããé«åºŠã«æé©åãããŠããŸããã 代ããã«å¿ èŠãªã®ã¯ãTypeScriptã䜿çšããŠãarity>1é¢æ°ã®åãååž°çã«æ§ç¯ããã³å解ããããšãåæ§ã«ç°¡åã«ããããšã ãšæããŸãã ããã¯ãã¹ãŠïŒ5453ã«æ»ã£ãŠãããšæããŸãã
ä»ã®äººã¯ãc ++ãéåžžã«ãã䌌ãæ©èœãæã£ãŠããããšãåŠã¶ã®ãé¢çœããšæããããããŸããïŒ decltypeïŒexpressionïŒ
ãã®æ©èœã¯TypeScriptã«çµã¿èŸŒãŸããäºå®ã§ããïŒ
åŒæ°ãåŒã§ããå
ã®ææ¡ããã圢åŒãéåžžã«å¥œã¿ãŸãããåŒã®äœçœ®ã«åãå«ãç¹å¥ãªæ§æãæã€ãšããTSããŒã ã®æå³ã¯ããã¹ãŠãè€éã«ããèšèªã«å°éããã®ãé
ãããŸãã
ãã®ãããã¯ãç¶æããå¿
èŠããããŸãã
ãã®ææ¡ã®ãµãã»ãããããå®è£
ã§ããã°æ¬åœã«å¬ããã§ãã ã€ãŸãããã®åäžã®ãã®ïŒ
type A = typeof anotherVariable
ã ãã®äžè¡ã§äœã§ãã§ããŸãã interface B extends A
ã <B & A>
: B & A
ãªã©
ç§ã¯Reactã§ãã®çš®ã®ãã®ã®å€ãã®ãŠãŒã¹ã±ãŒã¹ãèŠãŠããŸãã é«æ¬¡ã®ã³ã³ããŒãã³ããäœæããå ŽåããããçŸåšHOCã§ããããšãã³ã³ããŒãã³ãã¯ã©ã¹å®£èšã«ç€ºåããããšã¯ã¯ããã«å°é£ã§ãã
ç§ããã£ãããšã¯ã2ã€ã®ã¯ã©ã¹ãäœæããããšã§ãã 1ã€ã®ã¯ã©ã¹ãReact.Component
ãæ¡åŒµãããã¹ãŠã®è¿œå ã¡ãœãããè¿œå ããHOCé¢æ°å
ã®ã¯ã©ã¹ãrender()
ãæäœããŸãã
@blindbox type A = typeof anotherVariable
ã¯ãã§ã«æ©èœããŸãïŒ
var data = [1, 2, 3].map(v => ({ raw: v, square: v * v }));
function checkItem(item: typeof data) {
// item is Array<{ raw: number; square: number; }>
}
@IgorbekãããŒããã®éãã§ãã
ããŠãç§ã¯ãããç§ã®åŽã§ããŸããããªãã£ãçç±ãç解ããŸããã
ããã¯æ©èœããŸãã
interface B {
thisIsB: boolean
}
const typeTest = (type: any) => {
return 1 as any as App & B
}
type A = typeof typeTest(1)
declare const aVal: A; // aVal's type isn't of type App & B, but something else.
ãã ããããã¯æ©èœããŸãã
interface B {
thisIsB: boolean
}
const typeTest = (type: any) => {
return 1 as any as App & B
}
const typeTestVal = typeTest(1)
type A = typeof typeTestVal
declare const aVal: A; // aVal's type is of type App & B!
ããã§ãããåé¡ã¯ããžã§ããªãã¯åã®åŒæ°ã䜿çšããå¿ èŠãããå Žåãªã©ãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯äœ¿çšã§ããªãããšã§ãã
function someFunctionWithComplexReturnTypeThatUsesGenerics<T>(item: T) { ... }
// it is impossible to work this around because there's no chance to create a fake variable that would be parameterized by T
function use<T>(item: typeof someFunctionWithComplexReturnTypeThatUsesGenerics<T>(item)) { ... }
@Igorbek ïŒ
åŒæ°ãåŒã§ããå ã®ææ¡ããã圢åŒãéåžžã«å¥œã¿ãŸãããåŒã®äœçœ®ã«åãå«ãç¹å¥ãªæ§æãæã€ãšããTSããŒã ã®æå³ã¯ããã¹ãŠãè€éã«ããèšèªã«å°éããã®ãé ãããŸãã
ããã§ã圌ãããããæžããã®ã§ãç§ãã¡ã¯æååãšæ°åã®ãªãã©ã«ãæã«å ¥ããŸãããã€ãŸããç©äºã¯å°ãææ§ã«ãªã£ãŠããŸã-ãããã¯ã©ã¡ãã®æ¹æ³ã§ãæ©èœããŸãã ãªãã©ã«é åãšãªããžã§ã¯ããåæ§ã«ã¿ã€ãè¡šèšã«äŒŒãŠããããããããŸã§ã®ãšããè¯å¥œã§ãã
ãããã£ãŠãå€æ°ããžã§ããªãã¯ããã®ä»ã®ã¿ã€ããªã©ã®å€/ã¿ã€ããæ ŒçŽãããŠããŸãã ç©äºã圹ç«ã€ããã«ã¯ãããã§ãããã®äžéšãåãå
¥ããå¿
èŠã¯ãããŸããã
ããã§ã®ã¿ã€ãããŒã¹ã®ã¢ãããŒãã®è¯ãè°è«ã¯ããã®æ··åç©ãã¿ã€ãã¬ãã«ã§ç¡æã§èš±å¯ããããšã§ãã ã€ãŸããåã¬ãã«ã§ã¯ãã§ã«typeof myVar
ãšèšãããšãã§ããŸããã€ãŸãããã®é¢æ°'application'ãåã¬ãã«ã«è¿œå ãããšãæ ŒçŽãããŠããåãšéåžžã®å€æ°ã®äž¡æ¹ãèªåçã«ãã©ã°ã€ã³ã§ããããã«ãªããŸãã ã
æåã«ææ¡ãããã¢ãããŒãã«ã€ããŠã®ããªãã®ãããªãèããèŠãŠã¿ãããšæããŸãã 確ãã«ãããã¯ã¿ã€ãã¬ãã«ã«ããå°ãå
¬éããã®ã«åœ¹ç«ã€ãããããŸããïŒJSããŒã¹ã®æŒç®åïŒ !
&&
||
+
-
ãèããŠãã ãã*
/
instanceof
ïŒããã³TypeScriptåºæã®æŒç®åïŒã¢ãµãŒã·ã§ã³æŒç®å!
ïŒã
ãããã®JSæŒç®åã«ã€ããŠã®ããšã¯ã次ã®ãããªãã®ã§ã...ãªãã©ã«ãæäœããŠã察å¿ãããªãã©ã«çµæã¿ã€ããçæã§ããããã«ããããšã¯ãçŸåšã¹ã³ãŒãå€ãšèŠãªãããŠãããããçŸç¶ã§ã¯ã¿ã€ãã¬ãã«ã§ã¯ããªã圹ã«ç«ã¡ãŸããïŒ ref ïŒ--expression -ã¬ãã«1 + 1
ã¯ãã¿ã€ãnumber
ãçæããã ãã§ãä»ã®ã¿ã€ããåæ§ã§ãã
ããã念é ã«çœ®ããŠãç§ã¯åœŒãã®ã¿ã€ãããŒã¹ã®ææ¡ã«å°ãèœã¡èŸŒãã§ããŸãã
ãã®æ©èœã¯TypeScriptã«çµã¿èŸŒãŸããäºå®ã§ããïŒ [...]ãã®ãããã¯ãç¶æããå¿ èŠããããŸãã
ç§ã¯ãã®ææ¡ãããã§ã®ããå°ããªçç¶ã«å¯Ÿããããäžè¬çãªè§£æ±ºçãšããŠææ¡ããŸããããæåã¯éãããŠããŸããã
@ tycho01 typeof
ã®åŒããŒã¹ã®ããªãšãŒã·ã§ã³ã«é¢ããç§ã®è°è«ã¯ã@ yortusãæåã«è¿°ã¹ããã®ãšã»ãŒåãã§ãã
typeof
ïŒåã®äœçœ®ã«ããïŒã¯ãã§ã«åŒãåŠçããŠããŸãããåäžã®ã·ã³ãã«ãåãå
¥ããããã«å¶çŽãããŠããŸãã ãã®ãããåãŸãã¯ç䌌åŒã³åºããåãå
¥ãããšãïŒåŒãšåã«å ããŠïŒã¯ããã«å¥ã®æ§æãã©ã³ãã§ããã¯ããã«é¢åãªæ§æãå°å
¥ãããŸãã(undefined as any as <any arbitrary type can be here>)
ïŒã䜿çšã§ãããããå°ãªããšãåãšåãè¡šçŸåãæã¡ãŸãããåã·ã¹ãã ã«ã¯ãåŒã§è¡šçŸã§ããåããªãå ŽåããããŸãïŒspreadåãšreståã¯åŸã«å°å
¥ãããŸããïŒå¯Ÿå¿ããè¡šçŸãäžéžããŸããïŒããã®ãã€ã³ããpromised
PRã«æã£ãŠããŠãããŠããããšã@tycho01 ïŒç§ã¯å®éã«ããªãã®ã³ã¡ã³ãã®åŸã«ããã«æ¥ãŸããïŒãããã¯æ¬åœã«ãã®ãããªåçŽã§äžè¬çãªæ©èœãããŒãã³ã°ãªãã§éåžžã«ãšã¬ã¬ã³ããªæ¹æ³ã§ã¯ããã«è€éãªã·ããªãªãã«ããŒã§ããæ¹æ³ã瀺ããŠããŸãèšèªãžã®éåžžã«ç¹å®ã®æ¯ãèãã§ã
æ¡åŒµãããtypeof
ã¯ãåã·ã¹ãã ã®è¡šçŸåã®æ¬åœã®ã²ãŒã ãã§ã³ãžã£ãŒã§ãããããããããåã®ããã«èŠããŸã/ keyof
ã¯ãããè¡ããŸããã
@Igorbek ïŒè©³ãã説æããŠãããŠããããšããããããããªããã©ãããæ¥ãŠããã®ãããããŸãã ãããããããã2ã€ã®ã¢ãããŒãã¯ãç°ãªããŠãŒã¹ã±ãŒã¹ã«åœ¹ç«ã¡ãŸãã
çŸåšã®TSïŒãŸãã¯Playgroundã®2.3.3
ïŒã¯ãå
ã®ã·ããªãªã®å€ãããã§ã«æ©èœãããããšãã§ãããããå
ã®æçš¿ãããå
ã®ææ¡ã®ä»æ¥ã®äŸ¡å€ããããã瀺ããŠãããšæããŸãã
// I have a strongly-typed collection but the element type is anonymous/unknown, how can I reference the element type? (#3749)
// Mapping to a complex anonymous type. How to reference the element type?
var data = [1, 2, 3].map(v => ({ raw: v, square: v * v }));
declare function checkItem(item: typeof data[0]): any
// ^ no longer errors, needs no further change
// A statically-typed dictionary. How to reference a property type?
var things = { 'thing-1': 'baz', 'thing-2': 42 };
type Thing2Type = typeof things['thing-2'];
// ^ no longer errors, needs no further change
// A strongly-typed collection with special indexer syntax. How to reference the element type?
var nodes = document.getElementsByTagName('li');
type ItemType = typeof nodes.item(0);
// ^ the `.item` access works, but function applications still errors, would be fixed by either version of the proposal.
// A function returns a local/anonymous/inaccessible type, how can I reference this return type? (#4233, #6179, #6239)
// A factory function that returns an instance of a local class
function myAPIFactory($http: HttpSvc, id: number) {
class MyAPI {
constructor(http) {}
foo() {}
bar() {}
static id = id;
}
return new MyAPI($http);
}
declare function augmentAPI(api: typeof myAPIFactory(HttpSvc, number) /* ERROR */): any
// ^ function applications errors, would be fixed by either version of the proposal, if using slightly different syntax.
// I have an interface with a complex anonymous shape, how can I refer to the types of its properties and sub- properties ? (#4555, #4640)
// Declare an interface DRY-ly and without introducing extra type names
type MyInterface = {
prop1: {
big: {
complex: {
anonymous: { type: {} }
}
}
},
// prop2 shares some structure with prop1
prop2: MyInterface['prop1']['big']['complex'];
}
// ^ no longer errors after swapping `.k` access to `['k']`. `typeof` was unnecessary and counter-productive -- MyInterface isn't exposed on the expression level.
ãããã®äŸã¯ãåŒãŸãã¯åã®ã¢ãããŒãã®ã©ã¡ãã«ãåœãŠã¯ãŸããªããšæããŸããã»ãšãã©ã¯å»æ¢ãããŠãããç°¡åãªé¢æ°ã®é©çšã¯ã©ã¡ããã«ãã£ãŠå¯èœã«ãªããŸãã
確ãã«ãtinganhoãçŠç¹ãåœãŠãŠããã¿ã€ãã¬ãã«ããŒã¹ã®é¢æ°é©çšã§ã¯ãTSããŒã ãšç§ã¯ã typeof
ãä»ããŠåŒå€æ°ãå
¬éã§ããŸããããææã®ãšãããã¿ã€ãã¬ãã«ã¯ãåŒã§å
¬éãããæ©èœãããé
ããåŸåããããŸããã¬ãã«ã ãã®é¢æ°é©çšèªäœãšããªããèšåããã¹ãã¬ããæ§æã¯æããã«äž»èŠãªäŸã§ãããç§ã¯ãããã察åŠãããããšã絶察ã«æãã§ããŸãã ãããããçŸåšã®ã®ã£ããã®å€ãã¯ããã§åãçµãããšããã§ããŸãã
åæ§ã«ãåŒåªå
ã®ã¢ãããŒãã§ã¯ã <MyType> whatever
ãŸãã¯whatever as MyType
ã䜿çšããŠåãæ¿å
¥ããããšãã§ããŸãããåã¢ãããŒãã®typeof
ãšåæ§ã«ãåŸä»ãã®ããã«èŠããŸãã質åã¿ã€ã/ãžã§ããªãã¯ã¹ã«æ ŒçŽãããé¢æ°ã®é©çšã«ã€ããŠã¯ããã®ã¿ã€ãããŒã¹ã®ã¢ãããŒãã®å®éã®ä»å 䟡å€ã®å€§éšåãè£ãå¯èœæ§ããããŸãïŒããã§ã¯èšåãããŠããŸãããïŒ-é«éé¢æ°ã®æ£ç¢ºãªæšè«ãããã³ã¿ã€ãããŒã¹ã®æ¡ä»¶æãã®promised
ã¹ã¬ããã®ããã«ã*ããã«æªãããšã«ãOPã®ãŠãŒã¹ã±ãŒã¹ãšã¯ç°ãªãããããã«ã¯åé¿çããããŸããã
ã¢ã€ãã¢ãè¡çªããå ŽæãããããšæããŸããçŸåšã®ææ¡ã§ã¯ã typeof
ããŒã¯ãŒãããã®åŒãå€ã¬ãã«ã«åãæ¿ãããã©ããã«ã€ããŠãïŒç§ã®è§£éã§ã¯ïŒ typeof
ããã®ãŸãŸã«ããŠãããã©ããã«ã€ããŠççŸããèŠè§£ããããŸãã ããã ããåã¬ãã«ã§é¢æ°é©çšæ§æãå
¬éããŸãã
ç§ã®èŠè§£ã§ã¯ãççŸã¯å€å°å¶ç¶ã§ãã ç§ã¯ã©ã¡ãã®ãŠãŒã¹ã±ãŒã¹ã®æ£åœæ§ãç¡èŠããŸããã äž¡æ¹ãå®è£ ããå Žåãã»ãã³ãã£ã¯ã¹ã®è¡çªãåé¿ããè¿œå ã®ããŒã¯ãŒãã確èªã§ããŸãã ããŒã¯ãŒããã©ããªããã¯æ£çŽç¡é¢å¿ã§ããããããšãå ¥åãããã ãã§ãã
*ïŒãžã§ããªãã¯ã¹ã§åããã£ããã£ããã®ã§ã¯ãªãããã©ã¡ãŒã¿å
ã®é¢æ°ããã©ã¡ãŒã¿åã§åç
§ããããšã§ãããããé«éé¢æ°ã䜿çšããããšã«æ°ã¥ããŸããã
å®éã«ã¯ãç©äºã¯äž¡æ¹åã«å€æã§ããããã§ãã typeof
ã¯å€ã¬ãã«ããåã¬ãã«ã«æã¡äžããã®ã«åœ¹ç«ã¡ã declare let y: x;
ã¯ç©äºãå€ã¬ãã«ããåã¬ãã«ã«æã¡äžããã®ã«åœ¹ç«ã¡ãŸãã OPã®åé¿çã®ããã«ãšã¬ã¬ã³ãã§ã¯ãããŸããããããã§ãã
é¢æ°åãããšãã°æ瀺çãªãžã§ããªãã¯ã¹ãä»ããŠæã¡èŸŒãŸããå Žåãããã¯åœ¹ã«ç«ããªããšæããŸã-ãããã移åããæ¹æ³ããªããã°ãåã¬ãã«ã«ãªããŸãã
ãããç§ãå
å¶çã«æ©èœã®åºç€ãã«ããŒããããšãæãã§ããããã«èããããªããããã¯ããããæªè§£æ±ºã®ã¿ã€ãã³ã°ã®èª²é¡ã«é¢ããç§ã®é²æ©ã®å€ãããã®1ã€ã®ã¢ããªã³ã§ãããã¯ãããããã§ãïŒ5453ã«æ³šç®ããŠãã ããïŒã ãããããããã®ããšãç解ã§ããã°ãããã ãã®äŸ¡å€ããããŸãã
ç·šéïŒåŒããŒã¹ã®ã¢ãããŒãã§é€å€ãããå¯èœæ§ã®ããããã€ãã®çè«çãªã±ãŒã¹ã«ã€ããŠèããŸããããå®éã®åºæ¥äºã¯ãŸã é ã«æµ®ãã³ãŸããã§ããïŒ
declare function f<G extends (...args: any[]) => R, R extends <T>(foo: T) => Bar<T>>(g: G): typeof R(baz); // error following the expression-based proposal: R is not exposed at the expression level
ã ãã¡ããããããã¯ã G
ã®ãã©ã¡ãŒã¿ã¿ã€ããç¥ã£ãŠããŠæäŸã§ããã°èšç®ã§ããŸããããããŸã§ã®ãšããããã®æ
å ±ãååŸããæ¹æ³ã¯ãããŸããïŒããããïŒ14400ïŒïŒã ãã®ã«ããŽãªã«ã¯ãäžèšã®AngularJSã§äœ¿çšãããŠãããã¡ã¯ããªé¢æ°ã§åäœããé¢æ°ãå«ãŸãããšæããŸãã@Igorbekãã®ã¹ããããã§ããªããäœãæåŸ ããŠããã®ãããããŸããïŒ
function use<T>(item: typeof someFunctionWithComplexReturnTypeThatUsesGenerics<T>(item)) { ... }
埪ç°å®çŸ©ã®ããã§ãã
@masaeeduç³ãèš³ãããŸããããç§ã¯æå³ããŸããïŒ
ïŒ someFunctionWithComplexReturnTypeThatUsesGenerics
ïŒ$ã§ã¯ãªãf
ã«åãæ¿ããŸãïŒ
function use<T>(item: typeof f<T>(undefined as any as T)) { ... }
念ã®ããã«èšããšãããã¯çŸåšãåœã®å€æ°ãå°å ¥ããããšã§åé¿ã§ããªãããšã§ãã
const _typeofItem = f<T>(undefined as any as T); // no T here
function use<T>(item: typeof _typeofItem) { ... }
ãšããã§ã typeof
ã®æ¹ãåªå
床ãé«ããããçŸåšã®ææ¡ãã¡ã³ããŒã¿ã€ãã®ã¯ãšãªã¿ã€ãæŒç®åT[K]
ãšç«¶åããŠããããšã«æ°ã¥ããŸããã
typeof x[K]
çŸåšã (typeof x)[K]
ãæå³ããŸããããã§K
ã¯ã¿ã€ãã§ãtypeof x[k]
ã¯(typeof x)[k]
$ãæå³ããŸããããã§ã k
ã¯ã¿ã€ãã§ãã ãŸãtypeof x[k]
ã¯typeof (x[k])
$ãæå³ããŸããããã§k
ã¯åŒã§ãã$ïŒ$ 11 $ïŒ$ã¯æå³çã«åçã§ãããããå®éã«ã¯typeof (x[k])
ã奜ã¿ãŸããã確ãã«é倧ãªå€æŽã§ãã
Chromeã®éçºããŒã«ã䜿çšãããšãããã¡ã³ããŒæŒç®åã®æ¹ãåªå ãããŠããããšãããããŸããã ã©ãã§èŠã€ããŸãããïŒ
@Igorbek ïŒããããããå
ã®æçš¿ã®type Thing2Type = typeof things['thing-2'];
ããã§ã«æ©èœããŠããçç±ã®ããã§ãã
@dehli ïŒJSåŒã¬ãã«ãTSã¿ã€ãã¬ãã«ãšæ¯èŒããŠããŸã-ãããã¯åãã§ã¯ãããŸããã 1ã€ã¯ãã©ãŠã¶/ããŒãã§å®è¡ããããã1ã€ã¯TSã³ã³ãã€ã©ã§å®è¡ãããŸãã
å人çã«ã¯ãTypeScriptãã€ã³ããã¯ã¹ä»ãã®åã¢ã¯ã»ã¹ãããé«ãåªå
é äœã§åã¬ãã«ã®typeof
ã解決ããã®ã¯å¥åŠã ãšæããŸãã æ£çŽãªãšãããããã¯ç§ã«ã¯ã»ãšãã©ãã°ã®ããã«èŠããŸãã ïŒãã®ã±ãŒã¹ã¯å®éã«ãã¹ããããŠããã®ã ããããïŒ
@tycho01ã¬ããã£ã TSã¯JSãšåãåªå é äœã䜿çšãããšæããŸããã
@dehliçºçŸã¬ãã«ã¯åãã§ããããã åã¬ãã«ã§ã¯ãæ§æã¯äŒŒãŠããŸãããæååã§ã¯ãªãåãè¿ããšãããã®ã§ãã
åªå é äœã¯ã圌ããæ³å®ããŠããå¶éã®çµæãããããªããšç§ã¯æšæž¬ããŠããŸãã ãã®æ©èœãæ¡åŒµããå Žåããããã®èæ ®äºé ã¯ãã¯ãè³¢æã§ã¯ãªãããã«æããããããããªãããšãèªããŸãã
å¥ã®æ³šæç¹ãšããŠãææ¡ã®äž¡æ¹ã®ããŒãžã§ã³ãå®è£ ãããå Žåãæ¬åŒ§ã¯ããã®ããã«ã©ã®ã¬ãã«ã«ããããæ瀺çã«ä¿ã€ããã®å¹æçãªæ¹æ³ãšããŠã圹ç«ã¡ãŸãã 劥åã®ããã«èãããªããã®ãæãä»ãã®ã«èŠåŽããŠããŸãããããã§ãã
@Igorbekããã¯ãä»»æã®åŒã§ã®typeof
ã®äž»ãªæ®ãã®ãŠãŒã¹ã±ãŒã¹ã§ããïŒ ïŒ14400ãååŸããå Žåãç§ãééã£ãŠããªããã°ããã¬ãŒã³ãªãŠãŒã¶ãŒå®çŸ©åã䜿çšããŠreturnof
ãåŸãããŸãã
returnof
ãæäŸããŸãããtype Return<T extends () => R, R = any> = R;
// overloaded function
declare function f(item: number): number;
declare function f(item: string): boolean;
type fType1 = Return<typeof f>; // ??
type fType2 = typeof f(1); // number
type fType3 = typeof f('a'); // boolean
// generic function
declare function g<T>(item: T): T;
type gType1 = Return<typeof g>; // ??
type gType2 = Return<typeof g<number>>; // not supported syntax
type gType3 = typeof g(1); // number
type gType4 = typeof g<number>(1); // number
type gType5 = typeof g('a' as 'a'); // 'a'
ç§ã¯æ®ãã®ãã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ãèªèããŠããŸããããããã¯ãŸã çºèŠãããŠããªãããã§ãããç§ã«ãšã£ãŠæãç¡æµã§é åçãªã®ã¯æ¬¡ã®ãšããã§ãã
typeof
ã¯æšæºã®éè² è·è§£æ±ºã䜿çšããããã_æ¡ä»¶ä»ããããã¿ã€ã_ã¯ïŒ12424ã§ååŸã§ãããããã¯ããã«åŒ·åã§ãã @ tycho01ã¯ã promised
ã¿ã€ãã®ãšã¬ã¬ã³ããªäŸã瀺ããŠããŸãPRïŒ17077@masaeedu ïŒãã質åã§ãã çãããŒãžã§ã³ã¯ã @Igorbekãèšã£ãããšãšã»ãŒåãã§ãã 解決ãããå ·äœçãªèª²é¡ã®ããå°ã詳现ã«ã€ããŠã¯ãïŒ16392ã®ãå¿ èŠãªäž»ãªæ©èœããªã¹ãã«çããªã¹ãããããŸããããã§ã¯ãæªè§£æ±ºã®èª²é¡ãããããå¯èœã«ããå¯èœæ§ã®ããææ¡ã«çµã³ä»ããããšããŸããã
ãããïŒ
ReturnType
ãèãããšãããã§åé¡ãªãã¯ãã§ããreduce
/ map
/ filter
/ find
ã®ãããªãã®ã®æ£ç¢ºãªãªã¿ãŒã³ã¿ã€ããçªç¶èšç®ã§ããŸã-å埩ãšãã§ãã¯ãå«ããã®ã stdlib.d.ts
ã¯ããã§ã¡ãªããããããRamda/Lodashã®ãããªFPã©ã€ãã©ãªãã¡ãªããããããŸãã å®éã«ã¯ããã¹ãŠã®å
¥åãããã£ãŠããããã§ã¯ãããŸãããïŒã¿ãã«ããããªã¹ãã®ãããªé
åïŒããªããžã§ã¯ãã«å¯Ÿããmap
ããã³filter
ã®æäœã¯ã Partial
ãããé©åã«å
¥åã§ããŸãã ããã¯ãreduxïŒhttps://github.com/piotrwitek/react-redux-typescript/issues/1ãåç
§ïŒãAngularã®ngrxãªã©ã®ç¶æ
管çã©ã€ãã©ãªãããé©åã«å
¥åããããã«å¿
èŠã§ããé©åã«åæå®ãããmap
æäœããªããšãDRY'erã®å
¥åããŒã¿ããåã¬ãã«ã§ç®çã®çµæãèšç®ããæ¹æ³ããªãããã§ããflatMap
ã®ãããªæäœã®ã¢ã³ã©ããã¿ã€ããã®promised
ããããŒã¶ã«ãªã©0
é€æ°ãçŠæ¢ãããšèšãã®ã«åœ¹ç«ã€å¯èœæ§ããããŸããããã¯ãåºæ¬çã«ãïŒ4183ã®ãããã¯ã§ããåããæžç®ããããã®ããã¯ã§ãã ãŸã ã»ãšãã©ã®ãŠãŒã¹ã±ãŒã¹ãæ³åããŠããªããšæããŸãããããã§å®çŸã§ããŸãïŒäŸïŒ function div<B extends number, NotZero = { (v: '1') => 'whatever'; }({ (v: 0) => '0'; (v: number) => '1'; }(B))>(a: number, b: B)
ã éåžžãIdrisèšèªã¯ãé·ãã«å¯ŸããŠå®å
šãªãã¯ãã«/è¡åæŒç®ã§ã¢ããã¿ã€ãºããŸããããããå¿
èŠãªã®ã¯é«éé¢æ°ã®å Žåã®ã¿ã§ããIsUnion
ã䜿çšããŠãå
¥åã¿ã€ãã®Union<T>
/ NonUnion<T>
å¶çŽãè¡šçŸããæ¹æ³ãcurry
ã Function.prototype.bind
ã Promise.all
ãªã©ã®é¢æ°ã®å
¥åã«ã圹ç«ã¡ãŸãïŒå®å
šãªãªã¹ãã§ã¯ãªããä»ã®äººãææŠçãªãã®ãšããŠæããé¢æ°ã®äžéšã§ãïŒãswitch
ããžãã¯ãããã§ã¯é¢æ°ã®ãªãŒããŒããŒããã¿ãŒã³ãããã³ã°ã«ãã£ãŠè§£æ±ºãããŸããpromised
ïŒã®ãããã¯ã§ããããããããæ¡ä»¶ä»ãã¿ã€ããå¥åã¿ã€ãã¬ãã«ã®ã¿ã€ããã§ãã¯ãOmit
ã Overwrite
ãªã©ïŒãïŒ12424ã®ã³ã¡ã³ããåç
§ããŠãã ãããtoString
ã toLocaleString
ïŒãæååã€ã³ããã¯ã¹ã«è§£æ±ºãããããã«ãªããžã§ã¯ãã¿ã€ãããããã£ã¢ã¯ã»ã¹ãä¿®æ£ããæ¹æ³ãããã¿ã€ãã¡ãœãããããã以åã¯ã°ãªãããããçµã¿èŸŒã¿ãªããžã§ã¯ãããããã£ã¢ã¯ã»ã¹ã«äŸåããŠããä»ã®ãã¹ãŠã®ã¿ã€ãã®æäœã§ã toString
ãªããžã§ã¯ãã¢ã¯ã»ã¹ã«é¢é£ããã°ãªãããä¿®æ£ããå¯èœæ§ããããŸããç·šéïŒå·çæç¹ä»¥éãæ¡ä»¶ä»ãã¿ã€ãïŒïŒ21496ïŒã§åãããããŠãŒã¹ã±ãŒã¹ãåãæ¶ããŸããã
@Igorbekã®åŒåªå
ã¢ãããŒãã®ææ¡ã¯ïŒäžèšã®ãªã¹ãã®äžéšã®ããã€ãã®æªç¥ã®ã¢ããªã±ãŒã·ã§ã³ãå£ãå¯èœæ§ãç ç²ã«ããŠ-é
ã«å¡ãã€ã¶ãããã®ãæãã®ã§ãããå
·äœçãªããšã¯ãŸã èããŠããŸããïŒããã«ãå€ã¬ãã«ãšåã¬ãã«ã®éã®ã®ã£ãããåããããšãçŽæããŸããããã«ã¯ãçŸåšããã®é¢æ°ã¢ããªã±ãŒã·ã§ã³ïŒthisïŒ6606ïŒãspread / restïŒïŒ5453ïŒãã¢ãµãŒã·ã§ã³æŒç®å!
ïŒïŒ17370ïŒãå
±çšäœã¿ã€ããªã©ãå«ãŸããŸããã¿ã€ãã¬ãŒãã«ããæžç®ïŒïŒ4183ããã以å€ã®å Žåã¯äžèšã®å¶çŽã«ãã£ãŠéæå¯èœïŒããããŠãããããã£ãšé ã®ãŠã£ãºãããèããããšã¯ã§ããŸããã
ãã®å šäœçãªãã¬ãŒããªãã«ããã2ã€ã®æ¹æ³ïŒå®éã®ã¿ã€ãã¬ãã«ãã¿ã€ãã¬ãã«ã«åã蟌ãŸããã¢ã¯ã»ã¹ãããåŒã¬ãã«ïŒã§ãã¹ãŠã®åãæ©èœã«ã¢ã¯ã»ã¹ã§ããããã«ããçç±ãªã©ãããã€ãã®çåãçããå¯èœæ§ããããŸãã
ç·šéïŒè¿œå ã®æœåšçãªèª²é¡ã§äžèšã®ç§ã®æ¯èŒã³ã¡ã³ããæŽæ°ããŸããã
ç·šé2ïŒ
ããã§æ®å¿µãªã®ã¯ãå
ã®æçš¿ã§ã¯ã null &
ã®åé¿çããªããŠããäžéšã®ãšããžã±ãŒã¹ãèšè¿°ã§ãããšä¿¡ããŠããããšã§ãããå®éã«ã¯ãããã¯ãåšå²ã®ã³ã³ããã¹ãã«å¯Ÿããæ¢ç¥ã®åé¿çããªããçŸåšTSãæå¶ããŠããéèŠãªæ©èœã§ãã ã
ã€ãŸããåå¥ã®.d.ts
ãã¡ã€ã«ã«æžã蟌ãŸããTSã«åœ±é¿ããŸããããã¯ã stdlib.d.ts
ã ãã§ãªããå
ã®JSãããžã§ã¯ããšã¯å¥ã«æžã蟌ãŸãããã¹ãŠã®DTã¿ã€ãã³ã°ã®æšæºã§ãããå€æŽãããå¯èœæ§ã¯ã»ãšãã©ãããŸãããäžæ¹ãJSã©ã€ãã©ãªã¯ããããŒãªã©ã®ä»£æ¿æ段ã«å¯ŸããŠããªãŒãã³ã§ããç¶ããããšèããŠããŸãã
ïŒããã¯.ts
ã®åä»ãã«ã¯ããŸãé©ããŠããŸãããã€ãŸããOPã®ãåé¿çãã䜿çšããåã¯ãåŒã¬ãã«ã«åœ±é¿ãäžããã«ãããé«ãã¬ãã«ã®åå©çšå¯èœãªåã«æ§æãããªã©ããã©ã¡ãŒã¿ãŒåã§ããŸãããïŒ
@tycho01ãªã¹ããããããšãã ããã«ã¯ç§ãæ¶åããå¿ èŠã®ãããªã³ã¯ããããããããŸãã ã¿ã€ãã®ãã¿ãŒã³ãããã³ã°ãæ¬åœã«å¿ èŠã§ããïŒ6606ã¯ããã®åé¡ã«å¯Ÿããåªããå®çšçãªãœãªã¥ãŒã·ã§ã³ã§ãã ãã ããå€ã¬ãã«ãšã¿ã€ãã¬ãã«ã§ç©äºã®éã«æ··ä¹±ãçããŠããããã«æãããïŒ6606ã¯ãã®é åã§ç©äºãæ¹åããŸããã
ãã®æ©èœãå¿ èŠãªçç±ã¯ã以äžã«å¯Ÿå¿ããååŒãäœæããæ¹æ³ããªãããã§ãã
typeof K[L]
ã®åïŒæååãªãã©ã«åã®ããŒã«å¯Ÿå¿ãããªããžã§ã¯ãåã®ããããã£ã®åå€ã¬ãã«ã®æ§æãšåã¬ãã«ã®åŒãæ··ãåãããããšãªãããããã®çŽç²ãªåã¬ãã«ã®åŒãå®éã«æ§æã§ããã¯ãã ãšæããŸãã (a: A) => B
ãA | B
ã®ãããªåãã Func<A, B>
ã Union<A, B>
ã®ãããªåçŽãªãã©ã¡ãŒã¿ãŒåãããåã®ç ç³ã§ããããã©ã¡ãŒã¿ãŒåãããåãæäœããããã®äžè¬çãªããŒã«ãããã°ããã®ã§ããã ïŒHKTãfundepsãŸãã¯åæãªã©ïŒã
å¥å šæ§ã«é床ã«çŠç¹ãåœãŠãããšãTypeScriptã®ç®æšã®1ã€ã§ã¯ãªãããšã¯ç¥ã£ãŠããŸãããäžéæãªæ¹æ³ã§çžäºäœçšããã¿ã€ãã¬ãã«ã®æŠå¿µããããããããŸãã ã¿ã€ããšã¯äœãã®ããçš®ã®åœ¢åŒåãããã³ã¿ã€ããä»ã®ã¿ã€ããšã©ã®ããã«çžäºäœçšãããïŒãµãã¿ã€ãã³ã°ãç Žæ£ãªã©ïŒã®æ©æ¢°çã«ãŒã«ãèŠå®ããæ¹æ³ã¯å€§ãã«åœ¹ç«ã¡ãŸãã
å€ã¬ãã«ã®æ§æãšåã¬ãã«ã®åŒãæ··ãåãããããšãªãããããã®çŽç²ãªåã¬ãã«ã®åŒãå®éã«æ§æã§ããã¯ãã ãšæããŸãã
ãããããç§ã¯å人çã«ã䟡å€ã¬ãã«ã®æ§æèŠçŽ ã䜿çšããããšã«ãŸã£ããé Œãã€ããã¯ãããŸããã§ããããããç§ãè©Šã¿ãŠãããã¹ãŠã§ãã 䟡å€ã®ã¬ãã«ãäžå¯æ¬ ã ã£ããšããããç§ã¯ããã§è¡šçŸããŒã¹ã®ãã£ã³ãã«ãããããããŸããã ïŒP
å€ãšã¿ã€ãã¬ãã«ã®éã®ã®ã£ããã¯ã»ãšãã©çããªããšäºæ³ããïŒTC39ã¯TSãããéã移åããŸããïŒïŒãã®ã£ããã«ã¯ãã§ã«åªããã¿ã€ãã¬ãã«ã®ææ¡ããããŸãïŒä»¥åã®æçš¿ã®äžéšãåç §ïŒã
ã¡ãªã¿ã«ãããªãã®æ°ã®é¢æ°ã®åæå®ãäœæããããšã¯ãã»ãšãã©ã®ãŠãŒã¶ãŒã®çµéšã®ç¯å²å€ã«ãªãã ãããšç§ã¯ç解ããŠããŸãã
ç§ã®èŠæ¹ã§ã¯ãæšæºã©ã€ãã©ãªãšFPã©ã€ãã©ãªãé©åã«å
¥åããŠãTSãŠãŒã¶ãŒãããããèšè¿°ããæšè«ã§èªåçã«åŠçã§ããããã«ããå¿
èŠããããŸãã
TSã«ã¯ã¿ã€ãã¬ãã«ã®æŒç®åãããã€ããããŸãããå®éã®åé¡ã解決ããããšïŒäž»ãªäŸã¯ïŒ12215ã®Overwrite
/ Omit
ïŒã¯ãã«ãžã¥ã¢ã«ãªWebéçºè
ã«ãšã£ãŠãã±ããç§åŠã«å°ã足ããªãããã«æããããããããŸããã ã¡ãªã¿ã«ãããã¯æè¿ãŸã§ç§ãã¡ãé£ããŠè¡ã£ãŠãããŸããããããŠãããã¯ãŸã ãããã¿ã€ã/ã€ã³ããã¯ã¹/ã·ã³ãã«ãã«ãŒãã§ãããããŸããã
ïŒaïŒAïŒ=>BãŸãã¯A|ã®ãããªã¿ã€ããããã°ããã§ããã Bã¯ãFunc ãUnionãªã©ã®åçŽãªãã©ã¡ãŒã¿ãŒåãããã¿ã€ãã®ç ç³ã§ãã
ãããè£è¿ããŠããã©ã¡ãŒã¿åãããåããšã€ãªã¢ã¹/åæ§ç¯åãšããŠäœæã§ããŸãã Foo<Bar>
ããšãåæäœã§ã¯ãåçŽåããããã®ã§ãããã©ããã¯é¢ä¿ãããŸããã説æã«é©åãããã©ããããã§ãã¯ããã ãã§ãã
ããã¯stdlib.d.ts
ãšã»ãŒåãã§ãã foo[]
ããããŸããã Array<Foo>
ã®èª¬æãæºãããŠããããã Array.prototype
ã®åã§æ©èœããŸãã
ããããå®éã«ã¯ããã§ã¯ãããŸããã
type Union2<A, B> = A | B;
type TuplizeA<Tpl extends Union2<any, any>, A, B> = [Tpl[0], Tpl[1]];
// ^ sorry, no way to access union members through e.g. [0]
// type a = TuplizeA<1 | 2>;
type TuplizeB<Tpl extends any | any> = [Tpl[0], Tpl[1]];
// ^ sorry, no way to access union members through e.g. [0]
// type b = TuplizeB<1 | 2>;
type TuplizeC<Tpl extends Union2<A, B>, A, B> = [A, B];
type c = TuplizeC<1 | 2>;
// ^ need 3 arguments, maybe fixable with #14400
type TuplizeD<Tpl extends A | B, A, B> = [A, B];
// ^ need 3 arguments, maybe fixable with #14400
type d = TuplizeD<1 | 2>;
ããã§ããããŸã 解決ããŠããŸããããkubeã®ïŒ14400ãå®éã«åœ¹ç«ã€ããšã«æ°ã¥ããŸããã ãããŠãç§ã¯ä»æ¥ãæ©ãããªãã«äŒããŸããïŒ
å®éã®é¢æ°ã«ã€ããŠãåãããšãèšããŸããããã¯ãïŒ14400ãé¢æ°ã®æ»ãåã ãã§ãªãããã©ã¡ãŒã¿ãŒã®åãå®è¡ããå¯èœæ§ãããããšãæãåºããŠãã ããã
ãã®ã¢ãããŒãã§ã¯ãä»ã®ãšãããªãŒããŒããŒãã䜿çšããå¿
èŠããããŸããããã¯ãæ¡åŒµæ§ããªãããæ®å¿µã§ãããããã§ãã åã³äžè¬çã«ããããã«ãåºæ¬çã«ãããã®ïŒ6606ãã¿ãŒã³ãããã³ã°ãªãŒããŒããŒãã䜿çšããŠãããŸããŸãªã¢ãªãã£ã«å¯ŸããŠé©åãªãªãã·ã§ã³ãããªã¬ãŒããŸãã
ããã䜿çšããŠãããããäžè¬çã«ã¿ãã«ã¿ã€ãã«å€æããå¢åã¢ãããŒãã䜿çšããŠããããå埩åŠçããŠãäœããã®æ¹æ³ã§ããããæäœã§ãããšæããŸãã
ãŠããªã³ã®å Žåãã¿ãã«ã¿ã€ãã«å€æããããã®ããããããªæ¹æ³ãæãã§ããŸããã ãã ããä»»æã®é åºãè¿œå ãããããããªæ§æ/ããŒã¯ãŒããèããããŸããã
ç·šéïŒãããã®åŒ/ã¿ã€ãã¬ãã«ã®æ©èœã®ã®ã£ãããããäžåºŠç¢ºèªããã«ã¯ïŒ
!
ïŒïŒ17370ïŒïŒãã®ïŒ6606ã®åŸãããã¯è§£æ±ºãããŸã!
ã®äžè¬çãªã±ãŒã¹ã§ããããã®ïŒ6606ã¯å¶çŽïŒããšãã°ãäžèšã®NotZero
ïŒã§ãå®çŸã§ããŸããArrayLike
ã¯æäœã§ããŸããç§ã®èŠç¹ã§ã List
ã®æäœãåç
§ããŠãã ããã ãã®ïŒ6606ã䜿çšãããšãé©çšãããŠããªãé¢æ°ããparamsãæœåºã§ãããšæããŸãããé©çšæã«ïŒã€ãŸããæ£ç¢ºãªå
¥åå€ãååŸããããã«ïŒæœåºããã«ã¯ã5453ãå¿
èŠã§ããèŠããã«ããã®ææ¡ãäžéžãããšããŠããè¡šçŸã¬ãã«ãšåã¬ãã«ã®éã®æ©èœã®ã®ã£ããã¯ãããã§ã®è¡šçŸãã¬ãŒããŒã®ææ¡ã«å¯ŸããŠããã»ã©å€§ããªè°è«ã«ã¯ãªããªãã§ãããã 5453ãå ¥ã£ãŠããããããäœãæãã€ããªãã£ãã ãŸãããŸããªäŸå€ã«ã€ããŠã¯ãããã®å ã®æçš¿ã«èšèŒãããŠããåé¿çãåŒãç¶ãæå¹ã§ããããšã«æ³šæããŠãã ããã
ããŠãããã§ãç°¡åã«ã§ããè°è«ã¯ãåŒãã¬ãŒããŒã®ããªã¢ã³ãã§ã¯ãåã¬ãã«ããã©ãŒãªã³ã°æŒç®åã«è¿œãã€ãåã§ãã£ãŠãããã®æ©èœã¯JSãšåãæ§æã§å ¬éãããïŒåé¿çãªãïŒãšããããšã§ããåŠç¿æ²ç·ãæžããã
ç·šé2ïŒ
åãåŒã¬ãã«ã«æã£ãŠãããšããåŒææ¡ã®ããªãã¯1 as any as MyType
ã¯ãé¢æ°èªäœã§ãè«ççã«æ©èœããã¯ãã ãšæ°ã¥ããŸããã
ããã¯ãããããäž¡æ¹ã®ãã¬ãŒããŒã«ãã£ãŠæå¹ã«ãªãå®éã®æ©èœãããã¶ã䌌ãŠããããã«èŠããããšãæå³ããŸããå€èŠäžã®éãã¯ãé¢æ°é©çšã§å€æ°ã䜿çšããããã®typeof myVar
ïŒã¿ã€ããã¬ãŒããŒïŒãšmyVar
ïŒåŒãã¬ãŒããŒïŒã§æ§æãããŸãã ãããã®ã¿ã€ãã䜿çšããã«ã¯ã MyType
ïŒã¿ã€ããã¬ãŒããŒïŒãš1 as any as MyType
ïŒåŒãã¬ãŒããŒã代æ¿declare let a: any;
ã次ã«<MyType>a
ïŒã
ã©ã¡ãã®ASTã®å€æŽãããªãæ±ããããããã§ãã åŒãã¬ãŒããŒã¯ã代ããã«å€åŒãæãããã«typeof
çµåãå¿
èŠã§ãã ã¿ã€ããã¬ãŒããŒã¯ãæ¢åã®é¢æ°é©çšæ§æïŒ fn<T>(arg)
ïŒãåŒããã¿ã€ãã¬ãã«ã«ã³ããŒããäžèšã®Ryanã«ãã£ãŠææ¡ãããæ¢åã®å®è£
ã«ããã¯ããŸãã
ç§ã¯ããã次ã®ããã«ãªããšæããŸãïŒ
è¡šçŸãã¬ãŒããŒã®å ŽåïŒ
typeof expr
ã¿ã€ããã¬ãŒããŒã®å ŽåïŒ
MyType
1 as any as MyType
ïŒåŒã¬ãã«ã®ã¿ã€ãã¬ãã«ã«åŒã¬ãã«ã®ã¿ã€ãã¬ãã«ããããŸãããããã§ãããŸã§è§ŠããããŠããªãé¢é£ãããã¯ã®1ã€ã¯ããã®åã¬ãã«é¢æ°ãã¢ããªã±ãŒã·ã§ã³ãã§this
ãã€ã³ãã£ã³ã°ãæäŸããæ¹æ³ã§ãã çŸåšãJSã¯ãããFunction.prototype
ã¡ãœããã«äžæžãããããšãå§ä»»ããŠããŸãããçŸç¶ã§ã¯ããããã¯ã¿ã€ãã¬ãã«ã§ãããåŠçããæ¹æ³ãæ¬ ããŠããŸãã
F(MyA, MyB)
ïŒ F(this: MyFoo, MyA, MyB)
ãšããŠåŒã³åºãããå¯èœæ§ã®ããé¢æ°åF
(this: Foo, a: number, b: string) => SomeReturnType
ãäžããããå Žåã®ãã©ã³ãã ãªæ§æäŸã
this
ãã€ã³ãã£ã³ã°ãäžæžãããã«æ»ãåãèšç®ãããšã F(MyA, MyB)
ã®ããã«ãªããŸããããã¯ãã§ãã®ãããªé¢æ°ã䜿çšããããšãããšãåã¬ãã«ã®this
åŒæ°ãéåžžç¡èŠãããæ¹æ³ãåæ ããŠããŸããè¡šçŸã¬ãã«ã
ãã®æ§æäŸã®é·æïŒ
ãã®æ§æäŸã®çæïŒ
ã ãããããã¯ãã§ã«ãã®èšèªã«ãªã£ãŠããŸãïŒ
è奮ããããªãã§ãã ããã
@DanielRosenwasserã¯ãåã®ä»£ããã«ãªãã©ã«ã®é¢æ°åŒã³åºãã䜿çšã§ããããã«ãããã°ã§ããïŒ12146ãææããŸããã
_5ååŸ_
ã¿ããŒïŒ ç§ãã¡ãæ¬çªç°å¢ã§æ±ºããŠäœ¿çšããŠã¯ãªããªãæãããéªæªãªãã®ã ããããããã¯é åçã§ã...
interface String {
passthrough<T>(v: T): T;
}
// All work
type ANumber = "".passthrough(10 * 10);
type AString = "".passthrough("hello" + "world");
type AHelloWorld = "".passthrough("hello world");
type AnArbitraryThing = "".passthrough(Object.assign({hello: "world"}, {foo: "bar"}));
type ThisCraziness = "".passthrough((() => "cows are big dogs"));
ããã®ããããã®åé¡ã®Effort: Difficult
ã¯å°ãçãããããã«èŠãããã¡ãã§å¶ç¶ã«ãããè¡ã£ãããã«èŠããŸãã
@tycho01ãã楜ãã¿ãã ããã
@TheOtherSamP TypeScript 2.4.2ã§ãããè©ŠããŸãããããããã®ã¿ã€ãã¯ãã¹ãŠany
ã§ãããšæšæž¬ãããŸãã
@pelotomãããšã2.4.2ãš2.5.0ã§åäœããŠããŸã-dev.20170803ã es6ããã³strictã¢ãŒããã¿ãŒã²ããã«ããŸãã
圌ãã¯ã¡ããã©ãããä¿®æ£ããããã«èŠããŸããç§ã¯ãããç§ã®ãããããããªãã®ã§ã¯ãªãããšå¿é ããŠããŸãã ïŒ17628
@TheOtherSamPãããããµã€ã³ãã¯ãããŸããã ãããããªãã
@pelotomããã¯å¥åŠãªããšã§ããããã¯ç§ã«ãšã£ãŠå®å šã«æ°é®®ãªãããžã§ã¯ãã§åããŠããŸããç§ã¯ç§ãã¡ã®ã»ããã¢ããã«ã€ããŠäœãéãã®ãããããŸããã
@TheOtherSamP ïŒã¯ã¯ãããã¯ããªãé¢çœãã§ãã
æéçã«ã¯ãã³ã¡ã³ãã®å°ãåã«ä¿®æ£ãéå§ããããã§ãã ãããããªãã
@pelotom ïŒ
TypeScript 2.4.2ã§ãããè©ŠããŸãããããããã®ã¿ã€ãã¯ãã¹ãŠä»»æã§ãããšæšæž¬ãããŸãã
圌ã®ã¹ããããã¯PlaygroundïŒ2.3.2ïŒã§æ©èœããŠããããã§ãã ãã以å€ã®æè¿ã®ããŒãžã§ã³ïŒ ^2.5.0-dev.20170626
ïŒã§ã¯ãç§ãåçŸã«åé¡ããããŸãã
ãã®ããããã®åé¡ã®
Effort: Difficult
ã¯å°ãçãããããã«èŠãããã¡ãã§å¶ç¶ã«è¡ã£ãããã«èŠããŸãã
圌ãã¯åããŒã¹ã®å®è£
ãåç
§ããŠããŸããããããã¯ããã€ãã®å€æŽãæå³ããŸãããããã¯åŒèšèªã䜿çšããŠããããã§ãïŒ-> +
ã Object.assign
ããããªãé¢æ°åŒã³åºãïŒã
@ tycho01 ïŒ17618ã§æ³šç®ãéããããšããããã¹ãŠãå§ãŸã£ããšæããŸãã ãŸããããã¯ç§ã«ãããæ¬çªç°å¢ã§äœ¿çšããããšãåçå£ã«æ€èšããããšãæããŠãããŸãã
圌ãã¯ã¿ã€ãããŒã¹ã®å®è£ ãåç §ããŠããŸããããããã¯ããã€ãã®å€æŽãæå³ããŸãããããã¯åŒèšèªïŒ-> +ãObject.assignããããªãé¢æ°åŒã³åºãïŒã䜿çšããŠããããã§ãã
ãããç§ã¯ã°ãã§ããããèšããŸã§ãã®åé¡å šäœãèªã¿éããŸããã§ããã æ®å¿µã§ããããããããã®æ©èœã®ããè¯ãããŒãžã§ã³ã§ãããä»ããå ¥æã§ããã°ãšæããŸãã ç§ã¯åã·ã¹ãã ã®éçã倧ãã«æŒãäžããŸãããããŠãããïŒ12424ã®ã©ã¡ãããéåžžã«å€ãã®ãªãã·ã§ã³ãéãã§ãããã
ïŒ17961ã§PRãéå§ããŸããã
@yortusããã¯ãtypeofliteralãã®ã±ãŒã¹ãã«ããŒããŠããŸããïŒ
ä»æ¥ã®TypeScriptã§ã¯ããconst xïŒtypeof 1=1;ããšæžãããšã¯ã§ããŸããã
@NN ---å ã®ææ¡ã¯ãã¹ãŠã®åŒãã«ããŒããŠããŸãããç§ãç解ããŠããããã«ããæ¿èªããããéšåã¯ããããã£ã¢ã¯ã»ã¹ãšé¢æ°ã®æ»ãåã®ã¿ãã«ããŒããŠããŸãã
typeof 1
ãèš±å¯ãããŠãããšããŠãããªãã©ã«åïŒ 1
ïŒãŸãã¯ããåºãåïŒ number
ïŒã®ã©ã¡ããæäŸãããã¯ããããŸããã
ä»æ¥ã®TypeScriptã§ã¯ããconst xïŒtypeof 1=1;ããšæžãããšã¯ã§ããŸããã
ãªãconst x: 1 = 1;
ãªãã®ã§ããïŒ
@SaschaNazç§ã¯æ¬¡ã®ãããªãã®ãæžãããã£ã
const a = {q:1};
const b = {q:1};
const x: ReadonlyArray<typeof a> = [a,b];
ããããåæ§ã®ããšã¯ãªãã©ã«ã§ã¯æ©èœããŸããã
const x: ReadonlyArray<typeof 1> = [1,2,3];
@yortusæ£ç¢ºãªã¿ã€ãã«ã€ããŠã®è¯ãç¹ã ãªãã©ã«åã«ã€ããŠã¯èããŠããŸããã§ããã
@ NN ---ïŒããªãã®äŸã¯ãã§ã«æ©èœããŠãããšæããŸãã
@ tycho01ãããŒã«$Call
ã¿ã€ããè¿œå ãããé¢æ°ã®ãªã¿ãŒã³ã¿ã€ããååŸã§ããããã«ãªããŸããhttps://github.com/facebook/flow/commit/ac7d9ac68acc555973d495f0a3f1f97758eeedb4
typeof fn(...)
ã®ã¿ãèš±å¯ããããšã¯ãä»»æã®åŒã®typeof
ãèš±å¯ããããšãšåãã§ã¯ãªãã§ããããã
function fn() {
return /** whatever expression you like */;
}
type a = typeof fn();
ã¿ã€ããææ¡ãã以å€ã®ç®çã§ã©ã³ã¿ã€ã é¢æ°ãäœæããŠããå Žåãé€ããŸããïŒ
ããŸãã åŒã®å®è¡ã§ã¯ãªããåŒã®åè©äŸ¡ãè¡ã£ãŠããŸãã
@ dyst5422 typeof fn()
ã¯å®éã«ã¯åŒãè©äŸ¡ããããªã¿ãŒã³ã¿ã€ããæäŸããã ãã§ãã
ç·šéïŒå€åããã¯ããªããèšãããšããŠããããšã§ãã確ãã§ã¯ãããŸããã ãããã @ sky87ã¯ãé¢æ°ã_è©äŸ¡_ããã®ã§ã¯ãªããååŒã§äœ¿çšãã以å€ã®ç®çã§é¢æ°ã_defining_ããããšã«ã€ããŠè©±ããŠãããšæããŸãã
@ dyst5422 ã@ pelotomãèšã£ãããã«ãç§ã¯ããªããé¢æ°ãå®è¡ãããšããæå³ã§ã¯ãããŸããã§ããã ããã«è©³ãã説æãããšãä»»æã®åŒã®typeof
ã¯èš±å¯ããªãããé¢æ°ã®æ»ãåã®typeof
ã¯èš±å¯ããå Žåãããè€éãªåãç解ããããã«ç§ã¯äœãããŸããåŒã¯ããããé¢æ°ã§ã©ããããããšã§ããã®æ»ãåãèŠæ±ã§ããŸãã ããã«ãããå®è¡æã«é¢æ°ãäœæãããŸãããããã¯æ»ãåãååŸããããã ãã®ãã®ã§ãããäœæããã®ã¯ããå®åçã§ãã
ç·šéïŒããªãã¯å®éã«ãã§ã«ä»»æã®åŒã®ã¿ã€ããç解ããããšãã§ããŸããããã¯éãã§ããæ©èœããŸã
const dummy = (false as true) && /* arbitrary exp */;
type TypeOfExp = typeof dummy;
æ£çŽãªãšãããã©ã®ããã¯ã奜ããããããŸããã typeof
ã䜿ã£ãŠçŽæ¥ã¿ã€ããå°ããããã®ãäžçªãããšæããŸãã
ãããç§ã¯ä»ãã©ããŒããŸãã ãããç§ã¯ããã次ã®ããã«äœ¿çšã§ããããã«ããããšã奜ãŸããæ¹æ³ã ãšæããŸã
type TypeOfExp = typeof (
false &
"false" &
0
)
åŒåè©äŸ¡ãä»»æã«è¡ããããã«ãã
new
åŒã³åºãã®æ»ãã¿ã€ããç
§äŒããããšã¯å¯èœã§ããïŒ ç§ã®ãŠãŒã¹ã±ãŒã¹ïŒ PromiseConstructorLike
å®è£
ïŒ$ qãBluebirdãªã©ïŒãžã®åç
§ãåãå
¥ãããã®å®è£
ã«ãã£ãŠæ§ç¯ãããPromiseãè¿ãé¢æ°ã®åã¢ãããŒã·ã§ã³ãèšè¿°ããããšæããŸãã
declare function wait<P extends PromiseConstructorLike>(time: number, implementation: P): typeof new implementation<void>((res: any, rej: any) => void);
const bluebirdPromise = wait(1e3, Bluebird);
// typeof bluebirdPromise should be instance of Bluebird
typeof
ãªãã§è¿åã¿ã€ããç
§äŒããããšã¯å¯èœã§ããããããšãnull as FnType
ã«ããå¿
èŠããããŸããïŒ
interface Fn {
(a: string): string;
(a: number): boolean;
}
type Ret = Fn(number); // Ret = boolean
type Ret = typeof (null as Fn)(number);
ãããã®è³ªåããã§ã«åçãããŠããå Žåã¯ç³ãèš³ãããŸããã èŠã€ãããŸããã§ããã
ããã§ã®new
ã®ãã€ã³ãã¯äœã§ããã typeof implementation()
ã ããå¿
èŠã§ã¯ãããŸãããïŒ
ãããã implementation()
ã¯æå¹ãªåŒã³åºãã§ã¯ãªãããã§ãã PromiseConstructorLike
ã¯ãå宣èšã«åŸã£ãŠã new
ãä»ããŠã®ã¿åŒã³åºãããšãã§ããŸãã typeof implementation()
ã¯ã¿ã€ããšã©ãŒã§ããã (typeof implementation)['foobar']
ãã¿ã€ããšã©ãŒã§ããã®ãšåãã§ãã
FlowTypeãè¡ã£ããããªæšæž¬å¯èœãªãžã§ããªãã¯åãå°å ¥ããããšã¯å¯èœã§ããïŒ å°ãªããšããé¢æ°ã®æ»ãå€ã®åãååŸããããã®åé¡ã解決ã§ããŸãã
type _ExtractReturn<B, F: (...args: any[]) => B> = B;
type ExtractReturn<F> = _ExtractReturn<*, F>;
@Cryrivers ïŒãã®ã¢ãããŒãã«ã€ããŠã¯ïŒ14400ãåç §ããŠãã ããã ãã ããåºåã¿ã€ããå ¥åã«äŸåãããšããåé¡ã¯å®éã«ã¯è§£æ±ºãããŸããã
é¢æ°ã®åŒã³åºããåçã«äœãè¿ããã瀺åããããã«ãä»æ¥ããããå¿ èŠã«ãªããŸããããããåªå ãããããšãé¡ã£ãŠããŸãã
ReturnType<T>
æŒç®åã¯ãæ¡ä»¶ä»ãã¿ã€ããå©çšããŠãTS 2.8ã®lib.d.ts
ã«è¿œå ãããŠããŸãã
ReturnType<T>
ã¯ãåŒæ°ã®åã«äŸåããæ»ãåããŸã èæ
®ããŠããªããããåèã®ããã«ãFlowã®$Call
åã®å®è£
ã瀺ããŸãã
ç·šéïŒç³ãèš³ãããŸããã@goodmind ãç§ã¯ããªãããã§ã«æ£ç¢ºã«ããã«ãªã³ã¯ããŠããããšã«æ°ã¥ããŠããŸããã§ããã
æè¿ã®TSã®è¿œå ã«åºã¥ããŠããã®ææ¡ã®ãŠãŒã¹ã±ãŒã¹ïŒãŸãã¯ãã®ã¿ã€ãã³ãŒã«ã®è§£éïŒã®ä»¥åã®æçš¿ãæŽæ°ããŸããã
ãã¿ãŒã³ãããã³ã°ã®ãŠãŒã¹ã±ãŒã¹ã¯ïŒ21496ã§ã«ããŒãããããã«ãªãããŠãŒã¶ãŒãæäŸããã©ã ãã«åºã¥ããŠåãèšç®ãããå Žåãããšãã°curry
ãé¢æ°åæã map
ã reduce
ãã©ã ãã«åºã¥ããã¬ã³ãºç·šé...楜ãããã®ã :)
PS @ thorn0 ïŒAngularã®ãŠãŒã¹ã±ãŒã¹ã¯ReturnType
ïŒïŒ21496ïŒã§åãããããšæããŸãïŒ
ãã®è¡šçŸãèš±å¯ããããšã§ããããã«ããŒããå¿ èŠããããŸãã
prop2ïŒtypeof this.prop1.big.complex;
@mhegazyããã远跡ããããã®å¥ã®åé¡ã¯ãããŸããïŒ
éçããããã£ã§æ©èœããŠããã®ã«ãtypeofãããŒã«ã«ã§ã¯æ©èœããããããããã£ã§ã¯æ©èœããªãã®ã¯é¢åã§ãã
class A {
x: number;
static y: number;
f() {
const a: number = 1;
const b: typeof a = 2; // OK
const c: this.x = 3; // No :(
const d: this['x'] = 3; // OK
const e: typeof A.y = 4 // OK
}
}
@ NN ---ããã«ã¯ããã€ã§ãã€ã³ããã¯ã¹ä»ãã®åã䜿çšã§ããŸãã
this['x']
@cameron-martinåäœããŸããã éã³å Ž
@ tycho01æ°ããåã®æšè«ãšæ¡ä»¶æã¯çŽ æŽãããã§ãããé¢æ°ã®ãªãŒããŒããŒãã§ã¯æ©èœããªãããšãéåžžã«åä»ã§ãã äžããããçç±ã¯ãå¯èœãªãã®ããé¢æ°åã解決ããããã«ããã®typeof
ã®ãããªãã®ãå¿
èŠã ã£ãããã§ãã
@NNã¯const d: this['x'] = 3;
ã䜿çšããã ãã§ã
ããã ïŒïŒ
@NN---ãŸãã¯äœ¿çš
class A {
x: number;
static y: number;
f() {
const self = this;
const a: number = 1;
const b: typeof a = 2; // OK
const c: typeof self.x = 3; // OK
const d: typeof self['x'] = 3; // OK
const e: typeof A.y = 4 // OK
}
}
@tsofistå°å
ã§åããŠããããšã¯ç¥ã£ãŠããŸãããããã¯éãã§ãã
ããã¯ãæé»ã®ãã£ããã£ã§ã©ã ãã䜿çšãã代ããã«ããfunctionïŒïŒ{}ãã³ãŒã«ããã¯ã®ãthisããæåã§ä¿åããã®ãšåãã§ãã
@NN
ãã®éãã
ãããããã¯åãªããªãã·ã§ã³ã§ã:)
ç¹å®ã®åŒæ°ã®ã»ãããæ€èšŒããå Žåã¯ãç¹å®ã®ä»ã®ãšã€ãªã¢ã¹ãšäžç·ã«ReturnTypeOf<T>
ãèšè¿°ã§ãããããæ¡ä»¶ä»ãã¿ã€ãã§ã¯ãããã»ãšãã©ç¡é¢ä¿ã«ãªããŸãã 圌ãã¯éè² è·ã®è§£æ±ºãè¡ãããšã¯ã§ããŸãããããã®æ©èœã¯ãã®ãŠãŒã¹ã±ãŒã¹ã®ããã ãã«è€éã«ãã䟡å€ããããšã¯æããŸããã
@RyanCavanaughç§ã¯ããªããReturnType<T>
ãæå³ãããšæããŸããïŒ
æ®å¿µãªããšã«@RyanCavanaugh-éè² è·ã®è§£æ±ºã¯ç§ãæ¬åœã«å¿ èŠãšããŠãããã®ã§ãã æ¡ä»¶ä»ã/æšè«ã¿ã€ããžã®éè² è·è§£æ±ºã®è¿œå ã远跡ããå¥ã®åé¡ã¯ãããŸããïŒ
ããªãã¯ãããæžãããšãã§ããã¯ãã§ãïŒ
type Return1<A1, T extends (a: A1) => any> = T extends (a: A1) => infer R ? R : any;
type Return2<A1, A2, T extends (a: A1, a: A2) => any> = T extends (a: A1, a: A2) => infer R ? R : any;
declare function something(a: number): number;
declare function something(a: string): string;
declare function something(a: number, b: string): boolean;
type A = Return1<number, something>; // number
type B = Return1<string, something>; // string
type C = Return2<number, string, something>; // boolean
ãã ãããã¹ãã¯è¡ã£ãŠããŸãããåŒæ°ã®æ°ããšã«åå¥ã®ãã«ããŒãå¿ èŠã«ãªããŸãã
@ForbesLindesay ïŒ something
ã¯çŸåšãåŒã¬ãã«ã®å€æ°ã§ããããšãã°ãããã§typeof
ãåç
§ããŠïŒãŸãã¯ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠå®£èšããŠïŒä¿®æ£ããŸãã ç§ã¯å®éã«ã¯ãé©åãªãªã¿ãŒã³ã¿ã€ããçæããããã«ç®¡çããŠããŸããïŒ 2.8.0-dev.20180318
ïŒã
@ForbesLindesayæ®å¿µãªããããããããŸããããšã¯æããŸããã æšè«ã¡ã«ããºã ã¯ã_last_ã¡ãœããã®ãªãŒããŒããŒããéžæããŸãã
type Funcs = ((p1: string, p2: string) => void) & ((p1: number) => void);
type FuncPromise1<T> = T extends (p1: infer P1) => void ? (p1: P1) => Promise<[P1]> : never;
type FuncPromise2<T> = T extends (p1: infer P1, p2: infer P2) => void ? (p1: P1, p2: P2) => Promise<[P1, P2]> : never;
let foo: FuncPromise1<Funcs> & FuncPromise2<Funcs>;
ãã ããæšè«ã¡ã«ããºã ã¯ã¿ãã«ãŠããªã³ãåŠçã§ããŸãã
type Tuples = [string, string] | [number];
type TuplePromise1<T> = T extends [infer P1] ? (p1: P1) => Promise<[P1]> : never;
type TuplePromise2<T> = T extends [infer P1, infer P2] ? (p1: P1, p2: P2) => Promise<[P1, P2]> : never;
let foo: TuplePromise1<Tuples> & TuplePromise2<Tuples>;
ãªãŒããŒããŒã->ãªããžã§ã¯ããé¢æ°->ãªããžã§ã¯ããã¢ã³ã©ãããèš±å¯ãããã®ãå¿ èŠãªå ŽåããããŸãã ããã§åãããã³ã°ãšæšè«ãå®è¡ããŠãããé¢æ°ã«ã©ããããã¯ããŠãªãŒããŒããŒãããŸãã
@MeirionHughes ïŒ
ãªãŒããŒããŒã->ãªããžã§ã¯ããé¢æ°->ãªããžã§ã¯ããã¢ã³ã©ãããèš±å¯ãããã®ãå¿ èŠãªå ŽåããããŸãã ããã§åãããã³ã°ãšæšè«ãå®è¡ããŠãããé¢æ°ã«ã©ããããã¯ããŠãªãŒããŒããŒãããŸãã
(a: number, b?: string) => boolean
-> { a: number, b?: string }
ã®ããã«ïŒ ãã®ãããªãã©ã¡ãŒã¿åã¯ãŸã ååŸã§ããŸãããããªããžã§ã¯ãã¿ã€ãã䜿çšããŠé åºä»ããè¡ãããšãã§ããªããããæŠå¿µçã«ã¯ãRESTãã©ã¡ãŒã¿ïŒ (a: number, ...b: string[]) => boolean
ïŒã§ã¯ãããé£ãããªããŸãã
é åºã¯ããããååãããéèŠã§ããããã©ã¡ãŒã¿ãŒãšã¿ãã«ã®éã§å€æã§ããŸãã ã¹ãã¬ãã/ãªãã·ã§ã³ã¯ãããã§ãå°ãè€éã«ãªãå¯èœæ§ããããŸãã
ããã«ãããéè² è·ã®æœåºã«é¢ããåé¡ã軜æžãããŸãã ãªãŒããŒããŒãã¯((a: number) => 123) & ((s: string) => 'hi')
ã®ãããªé¢æ°åã®äº€å·®ã§ããå¿
èŠããããããåé¡ã¯äº€å·®åãïŒããšãã°ã¿ãã«åã«ïŒãã¢ã³ã©ãããããæ¹æ³ã§ããçŸæç¹ã§ã¯ãããã¯ãããŸããã
ãã®ãã¹ã¯ããªãŒããŒããŒãã®ãŠãŒã¹ã±ãŒã¹ã«å¯Ÿå¿ããŠãããã®ã®ããžã§ããªãã¯ãšã¯èšããªããããæºè¶³ã®ãããã®ã§ã¯ãããŸããããããã§ãã 亀差ç¹ã®ã¢ã³ã©ããã³ã°ã¯ããããã«ããŠããŸã ã®ã£ããã§ããã
ãã®å·ã¯çŸåšã¯ããŒãºãããŠããŸããããŸã äžè¶³ããŠããéšåã«ã€ããŠã®æ°ããææ¡ã¯ãŸã ãããŸããïŒ åŒæ°ã«å¿ããŠæ»ãåãåŠçããæ¹æ³ã®ããã«ïŒ
ãã®å·ã¯çŸåšã¯ããŒãºãããŠããŸããããŸã äžè¶³ããŠããéšåã«ã€ããŠã®æ°ããææ¡ã¯ãŸã ãããŸããïŒ
ç§ãç¥ã£ãŠãããã®ã¯ãããŸããã
åŒæ°ã«å¿ããŠæ»ãåãåŠçããæ¹æ³ã®ããã«ïŒ
ã³ãŒã«ã¿ã€ãã®è¿œè·¡ã«åé¡ããããšã¯æããªãã§ãã ããã
ã¿ã€ãã¬ãã«ã®é¢æ°é©çšãè¿œå ãããšããã¢ã€ãã¢ã®äºåçãªãµããŒãã¯ãããŸããïŒ ãã®ããã®ææ¡ãæžãããšãã§ããŸããã æ§æçã«ã¯ããããæãç°¡åãªæ¹æ³ã ãšæããŸãã
type MyType<A> = {
foo: A
}
type Wrap = {
<T>(maybe: MyType<T>): MyType<T>;
(maybe: any): MyType<any>;
}
type Naive = ReturnType<Wrap>; // Naive = { foo: any }
type Proposed1 = Wrap(maybe: number); // Proposed1 = { foo: number }
type Proposed2 = Wrap(maybe: MyType<number>); // Proposed2 = { foo: number }
type Proposed3 = (<T>(maybe: T) => MyType<T>)(maybe: number) // Proposed3 = { foo: number }
ãšããžã±ãŒã¹ïŒ
const foo = <T>(a: T) => T:
type Edge1 = (typeof foo)(a: number) // Probably trivial?
type Foo = {
<T>(a: string): T
}
type Edge2 = Foo<number>(a: string) // Should this be allowed? Probably not, because:
type Bar<A> = {
(a: string): A
}
type Edge3 = Bar<number>(a: string) // Things are getting strange
interface Baz<A> {
<T>(a: T): T | A
}
type Edge4 = Baz<number>(a: string) // What is this?
ã¿ã€ãã¬ãã«ã®é¢æ°é©çšãè¿œå ãããšããã¢ã€ãã¢ã®äºåçãªãµããŒãã¯ãããŸããïŒ ãã®ããã®ææ¡ãæžãããšãã§ããŸããã æ§æçã«ã¯ããããæãç°¡åãªæ¹æ³ã ãšæããŸãã
çŸæç¹ã§ã¯ãããŸããã ãªãŒããŒããŒãã®è§£æ±ºãé«æ¬¡ã®åã®ç©ºéã«å ¥ãããã¯ãããŸããã ãã®ããã»ã¹ã¯ããªãè€éã§ãåãã©ã¡ãŒã¿ãŒãæšæž¬ããããã®è€æ°ã®ãã¹ããã³ã³ããã¹ãã«å¿ããŠååŒæ°ãªã©ãå«ãŸããŸãããããé«æ¬¡ã§è¡ãããšã¯ãæåã¯å€ãã®äœæ¥ã§ããã次ã«ãã§åŠçããæºåãã§ããŠããªãããã©ãŒãã³ã¹ã®èª²é¡ãåŒãèµ·ãããŸããåœåã®éã
@mhegazyã¯ãïŒ24897ã®æè¿ã®äœæ¥ãèãããšãããã«å¯ŸããããŒã ã®ã¹ã¿ã³ã¹ããŸã£ããå€ããŸãããïŒ
ãã®è§£æ±ºçã$Call
ã¿ã€ãã«æžããããšãã§ããåé¡ã¯ããªãããããã§ãããŸãã $Call
ã¿ã€ãã¯ãããçš®é¡ã®å€ãã¿ã€ãããšãã¥ã¬ãŒãããæ¯èŒçç°¡åãªæ¹æ³ãžã®æãéããŸãã ããšãã°ã httpsïŒ//gist.github.com/hallettj/0fde5bd4c3ce5a5f6d50db6236aaa39eãåç
§ããŠãã ããïŒ $PropertyType
ãš$ObjMap
ã®äœ¿çšã$Call
ã«çœ®ãæããŸãïŒã ç·šéïŒè¿œå ã®äŸïŒ https ïŒ//github.com/facebook/flow/issues/30#issuecomment -346674472
ãã®ãããªæ©èœã¯ãééããªããå€ãã®åé¡ã«å¯Ÿããåççãªå ±éã®è§£æ±ºçãèŠã€ããTypeScriptã®å®çžŸãšäžèŽããŠããã§ãããã
ç¹å®ã®åŒæ°ã®ã»ãããæ€èšŒããå Žåã¯ãç¹å®ã®ä»ã®ãšã€ãªã¢ã¹ãšäžç·ã«
ReturnTypeOf<T>
ãèšè¿°ã§ãããããæ¡ä»¶ä»ãã¿ã€ãã§ã¯ãããã»ãšãã©ç¡é¢ä¿ã«ãªããŸãã 圌ãã¯éè² è·ã®è§£æ±ºãè¡ãããšã¯ã§ããŸãããããã®æ©èœã¯ãã®ãŠãŒã¹ã±ãŒã¹ã®ããã ãã«è€éã«ãã䟡å€ããããšã¯æããŸããã
@RyanCavanaugh @mhegazy
æ¡ä»¶ä»ãåã䜿çšããŠç©äºãè¡ãããšãå¯èœã§ããããšã«åæããŸãã User.avatar
ãUser extends { avatar: infer T } ? T : never
ã«æžãçŽããŠããã³ã³ãã€ã©ã«ããã»ã©è€éãã¯ããããããªããšæããŸããïŒ ããšãã°ã次ã®ããã«æžãããšãã§ããŸã
export type Avatar = User extends { avatar: infer T } ? T : never;
ãªã®ã§
export type Avatar = User.avatar;
èªã¿ããããåäžãããããã
ããã€ãã®ããŒã¿ãããŒãããŠå€æããæçµçã«æ¬¡ã®ãããªé¢æ°findUserãäœæãããšããŸãã
export function findUser() {
return {
username: 'johndoe',
avatar: {
lg: '1.jpg',
s: '2.jpg'
},
repos: [
{
name: 'ts-demo',
stats: {
stars: 42,
forks: 4
},
pull_requests: [
{ date: '2019-08-19', tags: ['bug', 'agreed-to-cla'] },
{ date: '2019-08-10', tags: ['bug', 'includes-tests'] },
{ date: '2019-08-07', tags: ['feature'] }
]
}
]
};
}
ããããããåããã®æšè«ã®ãããã§ã次ã®ããã«é¢æ°ããåãæœåºã§ããŸãã
export type User = ReturnType<typeof findUser>;
export type Avatar = User extends { avatar: infer T } ? T : never;
ææ¡ïŒããã¯åãããšãè©äŸ¡ããå¿ èŠããããŸã
export type Avatar = User.avatar;
ããã«ã User.avatar
ã®ã¿ã€ããnever
ã§ãã£ãŠã¯ãªããªããšæèšããããšãã§ããŸãã
ãã®ä»ã®äŸ
export type Repositories = User extends { repos: infer T } ? T : never;
export type Repository = User extends { repos: (infer T)[] } ? T : never;
export type RepositoryStats = Repository extends { stats: infer T } ? T : never;
export type PullRequests = Repository extends { pull_requests: (infer T)[] } ? T : never;
export type PullRequest = Repository extends { pull_requests: (infer T)[] } ? T : never;
export type Tags = PullRequest extends { tags: infer T } ? T : never;
export type Tag = PullRequest extends { tags: (infer T)[] } ? T : never;
export type Repositories = User.repos;
export type Repository = User.repos[];
export type RepositoryStats = User.repos[].stats;
export type PullRequests = User.repos[].pull_requests;
export type PullRequest = User.repos[].pull_requests[];
export type Tags = User.repos[].pull_requests[].tags;
export type Tag = User.repos[].pull_requests[].tags[];
ãã¹ããããããããã£ãäžåºŠã«ãããã³ã°ããå Žåãäœãèµ·ãã£ãŠããã®ããæ確ã§ã¯ãããŸãã
export type Tag2 = User extends { repos: { pull_requests: { tags: (infer T)[] }[] }[] } ? T : never;
ããã¯ããã倧ãã«æããã«ããã§ããã
export type Tag = User.repos[].pull_requests[].tags[];
export class Hello {
static world = 'world';
world = 42;
}
export type ThisWillBeANumber = Hello extends { world: infer T } ? T : never;
export type ThisWillBeANumber = Hello.world;
export type ThisWillBeAString = (typeof Hello) extends { world: infer T } ? T : never;
export type ThisWillBeAString = (typeof Hello).world;
@lukaselmerããªãã欲ããã ãã®ããã§ã
export type Avatar = User["avatar"];
ä»æ¥ã¯æ©èœããŸã
@lukaselmerããªãã欲ããã ãã®ããã§ã
export type Avatar = User["avatar"];
ä»æ¥ã¯æ©èœããŸã
ããããŸãã«ç§ãæ¢ããŠãããã®ã§ãã ããã¥ã¡ã³ãã§æ€çŽ¢ããŠããŸããããèŠã€ãããŸããã§ããã ããããšãïŒ
ããã¯ãã³ãããã¯ã®äžéšã§ããããããšããããã©ã®ããã«æ©èœãããã«ã€ããŠã®å ¬åŒããã¥ã¡ã³ãã¯ãããŸããïŒ ç§ã¯ããã䜿çšããæ¹æ³ã«ããªã粟éããŠããŸãããç§ã人ã ãããã¥ã¡ã³ãã«èªå°ããããšãããšãç§ãèŠã€ããããšãã§ããã®ã¯ã¿ã€ãã®èŠåå¡ã ãã§ããããã¯æ¬åœã«å®å šã«ç°ãªããŸã
ãã®ããããã®ææ¡ã¯2015幎ããè·³ãè¿ããåœåã®ç®æšã®1ã€ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã®åäžã®ããããã£ã®ã¿ã€ããäœããã®æ¹æ³ã§ååŸããããšã§ãã£ãããšã«æ°ä»ããŸããã
interface a {
foo: bar;
/* more types */
}
const example = (fooNeeded: [magic] a.foo ) => {};
ããã¯5幎åŸããŸã äžå¯èœã ãšæããŸããïŒ
@MFryããªãã¯ãã®æ§æãæ¢ããŠãããšæããŸãïŒ a['foo']
ããã«å¯Ÿãã解決çããŸã ãããã©ããç¥ã£ãŠããŸããïŒ
ç§ã¯ãã®ãããªãã®ãæã«å ¥ããããšããŠããŸãïŒ
declare function something<A, B>(): void;
type Payload = string;
const hello = something<{}, Payload>();
declare function doThing<T extends ReturnType<typeof something>>(arg: T): { payload: unknown };
doThing(hello).payload === 123; // this should validate to a string aka type Payload
https://www.typescriptlang.org/play/index.html?ts=4.0.0-dev.20200512#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwGccBbEDACy1QHMAeAQQBp4AhAPgAoBKALngDccWYAG4AUGIwBPAA4IAClCkQcUYPAC8hDDCrVxYsHgIZ45EBBWbCJMpRq0A3gF9mi5auCcuB0JFgIKOjYePDAOAAq9nQR8CAAHhggqMAE8ABKZMgwqBGyILTScjiINqQUemycsNR8EbzwjvAySipqfGgA1qg4AO74zr6R0RzmljhcAHQtHmqaGloAjABMAMwi8AD0m -AVaQTkOMgQ6vxQEMJQSbs48FDaujR3nfdFCq2eYkA
ããã«ã¡ã¯@maraisrç§ã¯ããªããäœãéæããããšããŠããã®ã100ïŒ
確信ãæãŠãŸããã ããªãã®äŸã§ã¯ã something
ã¯2ã€ã®ã¿ã€ããåããŸããããããã䜿çšããŸããã hello
ã¯ãåžžã«void
ã«ãªãäœãã®æ»ãå€ã§ãã ãããã£ãŠã doThing
ã¯ãã©ã®æç¹ã§ãã¿ã€ãstring
ãèªèããŸããã
ãã¶ãã以äžã®ãããªãã®ãããªããæããã®ã§ããïŒ
declare function something<ReturnType>(): ReturnType;
type Payload = string;
const hello = () => something<Payload>();
declare function doThing<F extends () => any>(f: F): { payload: ReturnType<F> };
doThing(hello).payload === 'a string';
ãããããããã«ã€ããŠã¯ããããªããã è¿ éãªå¯Ÿå¿ããããšãããããŸã!! ïŒ100ïŒ @acutmore
void
ã¯ããã®é¢æ°ã®returntypeãç¡é¢ä¿ã§ããããšã瀺ãããã ãã®ãã®ã§ããã ãããã®2ã€ã®åã¯ä»ã®ãžã§ããªãã¯åã«è»¢éãããæçµçã«åŒæ°ã§äœ¿çšãããŸãã
äœãã®ãããªãã®ïŒ
declare function something<A, B>(a: MyComplexGeneric<A>, b: B[]): { somethingA: number, somethingB: number };
// Those 2 generics influence the return object so they do get used as such. And the 2 arguments are roughly that. Its an object and an array, more-or-less.
ç§ã®doThing
é¢æ°ã¯ãæåã®ïŒ A
ïŒãžã§ããªãã¯ãäœã§ããããå®éã«ã¯æ°ã«ããŸãããã2çªç®ïŒ B
ïŒãäœã§ãããã¯æ°ã«ããŸãã
ç§èªèº«ã®ãŠãŒã¹ã±ãŒã¹ã®something
ã¯ã doThing
ã«ãã£ãŠèªã¿åãããå¯äœçšãå®è¡ããããšã確èªããŠãã ããã
ãããã£ãŠãé¢æ°ã®ReturnTypeãåçŽã«ååŸããããšã¯ã§ããŸãããäœæãããé¢æ°ã®ãžã§ããªãã¯ããªããšãããŠåžãåºãå¿ èŠããããŸãã
ãã®ã¯ãšãªããã®åé¡ã®ç¯å²ãè¶ ããŠãããšæãããå Žåã¯ãStackOverflowã§ç§ã®æ ãç¶ããŠãã ããïŒ
@maraisrè¿œå æ å ±ãããããšãã
doThing
ã§å
ã®B
ã¿ã€ããsomething
ããååŸã§ããããã«ããå Žåã¯ãäœããã®æ¹æ³ã§hello
ã«æž¡ãå¿
èŠããããŸãã TypeScriptã¯hello
ã®ã¿ã調ã¹ãŠãããå©ãããªããã°ããããsomething
ã®ãªã¿ãŒã³ã¿ã€ãã§ããããšãããããŸããã
ããã¯ããããå®è¡ã§ãã1ã€ã®æ¹æ³ã§ãã
/** Create a type that can store some extra type information **/
interface SomethingResult<T> {
__$$__: T;
somethingA: number;
somethingB: number;
}
declare function something<A, B>(): SomethingResult<B>;
type Payload = string;
const hello = something<{}, Payload>();
declare function doThing<Result extends SomethingResult<any>>(arg: Result): { payload: Result['__$$__'] };
doThing(hello).payload === 1123; // error because `payload` is of type string
interface User {
avatar: string;
}
interface UserData {
someAvatar: User['avatar'];
}
@RyanCavanaughãªããããééãããŠããã®ã§ããïŒ æ¡ä»¶ä»ãã¿ã€ãã¯ããããä»ã®å€ãã®ãŠãŒã¹ã±ãŒã¹ã解決ããŸããããããããŒãžãããšãéåžžã«å€ãã®ããšãå¯èœã«ãªããŸãã
ç§ã¯ãä»»æã®ã¡ãœããåŒã³åºããããã€ã³ãããªãŒãããŒãžã§ã³ã«å€æã§ããé¢æ°ã«åãçµãã§ããŸãïŒäŸïŒ [].map(() => n > 5)
ã¯map(() => n > 5)([])
ã«å€æãããäžè¶³ããŠããã®ã¯æ¡ä»¶åãšinfer
ã ãã§ãã unknown
ãšããŠåºåãããŸãã
é¢æ°ããåŒã³åºãããŠåïŒ typeof myFunc(() => Either<string,number>)
ïŒãååŸã§ããã°ããã®æ©èœïŒçŸåšã¯äžå¯èœïŒã䜿çšããŠãä»ã®å€ãã®ããšïŒHKTãªã©ïŒãã¯ããã«ç°¡åã«ããããšãã§ããŸãã ãïŒ
$Call
ãé¢æ°ïŒãããŒã®ããã«ïŒã«ã§ããããã«ããããã®è€éãã¯éåžžã«é«ãã§ããïŒ typescriptã¯ãã§ã«ãããèªåçã«è¡ã£ãŠãããããªæ°ãããŸãã
@nythroxãããããããå¯èœæ§ã®ããæ§æäžã®æ··ä¹±ããããã¿ã€ãã«å°éããããã«å¿ èŠãªå ŽåãããéèŠã§ãããšã¯æããŠããŸããã åŒã³åºãåŒã解決ããç¹å®ã®ã±ãŒã¹ã¯ãä»ã®å Žæã§è¿œè·¡ãããŸãã OPã§ã®ãããããè¡šçŸãèš±å¯ããããšããææ¡ã¯ããã®èšèªã«é©ããŠãããšã¯æãããŸããã
@RyanCavanaughãããããããŸããã è¿ä¿¡ããããšãããããŸããé¢æ°åŒã³åºãã®è§£æ±ºã远跡ããŠããåé¡ãç¥ã£ãŠããŸããïŒ
å°ã調ã¹ãŠã¿ãŸããããé¢æ°åŒã³åºããŠãŒãã£ãªãã£ã¿ã€ãã®åé¡ã¯èŠã€ãããŸããã§ããã ç§ãèŠã€ãããã®ãžã®å¯äžã®åç §ã¯ããã®åé¡ã«ãªã³ã¯ããŠããïŒ20352ã«ãããŸããã
åŒã³åºãåŒã解決ããç¹å®ã®ã±ãŒã¹ã¯ãä»ã®å Žæã§è¿œè·¡ãããŸã
@RyanCavanaughãã€ã³ãã¯ä»ã®å Žæã«ãªã³ã¯ããŠããŸããïŒ ð
@tjjfvi ïŒ37181ã¯ãããå ·äœçã«ã¯ãå ¥åã«åºã¥ããŠé¢æ°ã解決ããããšã«é¢ãããã®ã§ãã ããªããæ¢ããŠãããã®ãããããŸããã
@acutmoreããã¯ç§ãæ¢ããŠãããã®ã«ãããã沿ã£ãŠããŸããããããŒé¢šã®$Call
ãŠãŒãã£ãªãã£ããŸãã¯ãã®ãããªå®è£
ãå¯èœã«ããä»ã®æ§æã«ã€ããŠå
·äœçã«è©±ããŠããŸããã ã¢ãããŒãã¯å¥åŠãªããšã瀺åããŸãããããªã³ã¯ã«æè¬ããŸãã
æãåèã«ãªãã³ã¡ã³ã
ïŒ17961ã§PRãéå§ããŸããã