TypeScriptã«ã¯ãå®çŸ©Symbol
ãå«ãES6ã¿ãŒã²ããã¢ãŒãããããŸãã ãã ããã·ã³ãã«ã䜿çšããŠãªããžã§ã¯ãã«ã€ã³ããã¯ã¹ãä»ããããšãããšããšã©ãŒãçºçããŸãïŒã€ã³ããã¯ã¹åŒã®åŒæ°ã¯ããæååãããæ°å€ãããŸãã¯ãä»»æãã®ã¿ã€ãã§ããå¿
èŠããããŸãïŒã
var theAnswer = Symbol('secret');
var obj = {};
obj[theAnswer] = 42; // Currently error, but should be allowed
ããã¯ã @ JsonFreemanãåãçµãã§ããES6ã·ã³ãã«ãµããŒãã®äžéšã§ãã ã³ãŒããµã³ãã«ã¯ã次ã®ãªãªãŒã¹ã§ãµããŒããããäºå®ã§ãã
@wereHamster ããã«ãªã¯ãšã¹ãïŒ1978ã䜿çšãããšãããã¯åæ³ã«ãªãã¯ãã§ããã obj[theAnswer]
ã¿ã€ãã¯any
ãŸãã ããªããæ¢ããŠãããã®ã«ã¯ããã§ååã§ããããããšããã匷åãªã¿ã€ãã³ã°ãå¿
èŠã§ããïŒ
ã·ã³ãã«ã§ã€ã³ããã¯ã¹ä»ããããããããã£ã®ã¿ã€ããæå®ããããšã¯å¯èœã§ããïŒ æ¬¡ã®ãããªãã®ïŒ
var theAnswer = Symbol('secret');
interface DeepThought {
[theAnswer]: number;
}
ãã®PRã®ã³ã¡ã³ãã«åºã¥ããŠããããïŒ
_ããã¯ããªããžã§ã¯ããä»»æã®ã·ã³ãã«ããŒãæã€ããããšããŠæ©èœã§ããããã«ããã·ã³ãã«ã€ã³ãã¯ãµãŒã«ã¯é©çšãããŸããã_
@wereHamsterã¯
var theAnswer = Symbol('secret');
interface DeepThought {
[Symbol.toStringTag](): string; // Allowed
[theAnswer]: number; // not allowed
}
次ã®ã¬ãã«ã®ãµããŒãã¯ãã·ã³ãã«ã€ã³ãã¯ãµãŒãèš±å¯ããããšã§ãã
var theAnswer = Symbol('secret');
interface DeepThought {
[s: symbol]: number;
}
var d: DeepThought;
d[theAnswer] = 42; // Typed as number
ããã¯ç§ãã¡ã®ã¬ãŒããŒã«ãããç°¡åã«å®è£ ã§ããŸãã
æ匷ã®ã¬ãã«ã¯ããªããæ±ããŠãããã®ã§ãããããã¯æ¬¡ã®ãããªãã®ã§ãã
var theAnswer = Symbol('secret');
var theQuestion = Symbol('secret');
interface DeepThought {
[theQuestion]: string;
[theAnswer]: number;
}
var d: DeepThought;
d[theQuesiton] = "why";
d[theAnswer] = 42;
ããã¯æ¬åœã«çŽ æŽãããããšã§ããããããŸã§ã®ãšããããã®ããã®è³¢æãªèšèšã¯èããããŠããŸããã æçµçã«ã¯ãã¿ã€ãããããã®ã·ã³ãã«ã®å®è¡æã®å€ã«äŸåãããããšã«ããã£ãŠããããã§ãã ããã¯æããã«æçšãªããšãªã®ã§ãç§ãã¡ã¯ããã«ã€ããŠèãç¶ããŸãã
ç§ã®PRã§ã¯ãå°ãªããšãã·ã³ãã«ã䜿çšããŠãªããžã§ã¯ãã®å€ããã«ã¢ãŠãã§ããã¯ãã§ãã any
ã«ãªããŸããããšã©ãŒã¯çºçããªããªããŸãã
@wereHamsterç§ã¯ããªããèå³ãæã£ãŠãããããããªãå°ããªèšäºïŒ2012ãããŸããã
ãªã¯ãšã¹ãïŒ1978ãããŒãžããŸãããããã®å€æŽã§æäŸãã以äžã®ãã®ãèŠæ±ããŠããããã«èŠããããããã®ãã°ã¯éãããŸãŸã«ããŠãããŸãã ãã ããç§ã®å€æŽã«ãããå ã®ãšã©ãŒã¯ãªããªããŸãã
@wereHamsterããã§ãã£ãšäœãèµ·ãã£ãŠã»ãããã«ã€ããŠã®ææ°æ å ±ãæçš¿ã§ããŸããïŒ ç§ãã¡ãäœãå®è£ ããã®ããããªããäœãæçš¿ããã®ããããã«ã¯ããããŸããã§ãã
symbol
ãã€ã³ãã¯ãµãŒãšããŠæå¹ãªã¿ã€ãã«ãªããšãã®ã¢ã€ãã¢ã¯ãããŸããïŒ ããã¯ã³ãã¥ããã£PRãšããŠã§ããããšã§ããïŒ
ããã«ã¯PRãããŸãã @JsonFreemanã¯ãçºçããå¯èœæ§ã®ããããã€ãã®åé¡ã®è©³çŽ°ãæäŸã§ããŸãã
å®éãã·ã³ãã«ã€ã³ãã¯ãµãŒãè¿œå ããã®ã¯éåžžã«ç°¡åã ãšæããŸãã å²ãåœãŠå¯èœæ§ãååŒæ°ã®æšè«ãªã©ã®ç¹ã§ã©ã¡ããšãäºææ§ããªãããšãé€ããŠãæ°å€ãæååãšåãããã«æ©èœããŸããäž»ãªèª²é¡ã¯ãé©åãªå Žæãã¹ãŠã«ããžãã¯ãè¿œå ããããšãå¿ããªãããã«ããããšã§ãã
@RyanCavanaugh ãæçµçã«https://github.com/Microsoft/TypeScript/issues/1863#issuecomment -73668456typecheckã«æåŸã®äŸããããšäŸ¿å©ã§ãã ãã ããå¿ èŠã«å¿ããŠããã®åé¡ãè€æ°ã®å°ããªåé¡ã«åå²ããŠãäºãã«ç©ã¿éããããšãã§ããŸãã
ãã®é¢ã§äœãæŽæ°ã¯ãããŸãããïŒ AFAIUã®ææ°ããŒãžã§ã³ã®ã³ã³ãã€ã©ã¯ã httpsïŒ //github.com/Microsoft/TypeScript/issues/1863#issuecomment-73668456ã§èª¬æãããŠããæåã®ã¬ãã«ã®ã¿ããµããŒãã
ãã®å€æŽã®PRãåãã§åãå ¥ããŸãã
2ã€ã®å¥ã ã®åé¡ãšããŠ2ã€ã®ã¬ãã«ã远跡ãã䟡å€ããããããããŸããã ã€ã³ãã¯ãµãŒã¯ããªãåçŽã«èŠããŸããããŠãŒãã£ãªãã£ã¯æ確ã§ã¯ãããŸããã äžå®ã®è¿œè·¡ã«ããå®å šãªãµããŒãã¯éââåžžã«é£ããããã§ããããããããã£ãšäŸ¿å©ã§ãã
äžå®ã®è¿œè·¡ã¯ã httpsïŒ//github.com/Microsoft/TypeScript/issues/5579ã§ãã§ã«è¿œè·¡ãããŠã
äºè§£ããŸãããçã«ããªã£ãŠããŸãã
@JsonFreeman @mhegazyåé¡ã¯ïŒ12932ã§å ¥æã§ããŸã
ãŠãŒã¹ã±ãŒã¹ããªã³ã°ã«æã蟌ããšæã£ãã ãã§ãã ä»»æã®ãªããžã§ã¯ãããããã£ãšç §åããããã®ãã¬ãŒã³ããã¹ãããŒãšãç §åæŒç®åãæå®ããããã®èšå·ãæå®ããããšã§ãã¯ãšãªãèšè¿°ã§ããããŒã«ãäœæããŠããŸãã ããç¥ãããŠããæŒç®åã«èšå·ã䜿çšããããšã§ãããç¥ãããŠããæŒç®åã®ããŒãšåãããŒãæã€ãã£ãŒã«ããšæŒç®åãç §åãããšãããããŸãããåé¿ããŸãã
JavaScriptã§æ瀺çã«èš±å¯ãããŠããã®ãšã¯å¯Ÿç
§çã«ãã·ã³ãã«ãã€ã³ããã¯ã¹ããŒãšããŠæå®ã§ããªããããå€ãã®å Žæã§<any>
ã«ãã£ã¹ãããå¿
èŠããããã³ãŒãã®å質ãäœäžããŸãã
interface Query {
[key: string|symbol]: any;
}
const Q = {
startsWith: Symbol('startsWith'),
gte: Symbol('gte'),
lte: Symbol('lte')
}
const sample: Query = {
name: {
[Q.startsWith]: 'M',
length: {
[Q.lte]: 25
}
},
age: {
[Q.gte]: 18
}
};
ã¯ãšãªãšã³ãžã³ãæ€æ»ããå¿
èŠã®ããããŒã¿ã®å€æ§æ§ãèãããšã $
æåãªã©ã®ãããããããªããæåã®æåã®äœ¿çšã¯é©åãªåŠ¥åæ¡ã§ã¯ãããŸããã
ããã«ã¡ã¯ãã¿ããªã ããã«åãã¯ãããŸããïŒ ç§ã¯ãããå¿ èŠãªã®ã§ãå¿ èŠãªå€æŽãåãã§æäŸããŸãã ãã ãããããŸã§TSã«è²¢ç®ããããšã¯ãããŸããã
@mhegazy @RyanCavanaughçãããéåžžã«å¿ããããšã¯ç¥ã£ãŠããŸãããæ©äŒãããã°ãã²åå ããŠãã ããã ã·ã³ãã«ã¯ãã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ãèšèšããããã®éåžžã«éèŠãªããŒã«ã§ãããã€ã³ã¿ãŒãã§ã€ã¹ã§ã·ã³ãã«ã䜿çšããæ©èœã®æ¬ åŠã¯ãæ確ãªåé¡ç¹ã§ãã
äœãé²è¡äžã¯ãããŸããïŒ ãã®æ©èœããµããŒããããããšãå¿ããé¡ã£ãŠããŸãã
https://github.com/Microsoft/TypeScript/pull/15473ã¯é¢é£ããŠããããã«èŠããŸãã
ãããä»æ¥ããããæ¢ããŠããŸããããã¯ç§ãWebstormã§èŠããã®ã§ãïŒ
ããã¯å®éã«æ©èœããŸã
var test: symbol = Symbol();
const x = {
[test]: 1
};
x[test];
console.log(x[test]);
console.log(x['test']);
ãããã x
ã®ã¿ã€ãã¯æ£ãããªãã次ã®ããã«æšæž¬ãããŸãã
{
[key: string]: number
}
ãããä»æ¥ããããæ¢ããŠããŸããããã¯ç§ãWebstormã§èŠããã®ã§ãïŒ
WebStormãintelliJIDEAãªã©ã§ããã©ã«ãã§æå¹ã«ãªã£ãŠããJetBrainsç¬èªã®èšèªãµãŒãã¹ã«æ³šæããŠãã ããã
ããã¯TS2.7ã§æ©èœããŸã
const key = Symbol('key')
const a: { [key]?: number } = {}
a[key] = 5
ããã«é¢ããæŽæ°ã¯ãããŸããïŒ
ç§ã®åé¡ïŒ
export interface Dict<T> {
[index: string]: T;
[index: number]: T;
}
const keyMap: Dict<number> = {};
function set<T extends object>(index: keyof T) {
keyMap[index] = 1; // Error Type 'keyof T' cannot be used to index type 'Dict<number>'
}
ãã ããã·ã³ãã«ãã€ã³ããã¯ã¹ã¿ã€ãã«ããããšã¯ã§ããªãããããããæ©èœããŸããã
export interface Dict<T> {
[index: string]: T;
[index: symbol]: T; // Error: An index signature parameter type must be 'string' or 'number'
[index: number]: T;
}
äºæ³ãããè¡åïŒ
symbol
ã¯æå¹ãªã€ã³ããã¯ã¹ã¿ã€ãã§ããå¿
èŠããããŸã
å®éã®åäœïŒ
symbol
ã¯æå¹ãªã€ã³ããã¯ã¹ã¿ã€ãã§ã¯ãããŸãã
as string | number
ããã£ã¹ãããŠåé¿çã䜿çšããããšã¯ãç§ã«ã¯éåžžã«æªãããã§ãã
util.promisify.custom
ã¯TypeScriptã§ã©ã®ããã«äœ¿çšãããããšã«ãªã£ãŠããŸããïŒ å®æ°ã·ã³ãã«ã®äœ¿çšã¯çŸåšãµããŒããããŠããããã§ãããæ瀺çã«å®çŸ©ãããŠããå Žåã«éããŸãã ãããã£ãŠãããã¯æå¹ãªTypeScriptã§ãïŒ f
ãåæåãããŠããªãããšãé€ããŠïŒïŒ
typescript
const custom = Symbol()
interface PromisifyCustom<T, TResult> extends Function {
[custom](param: T): Promise<TResult>
}
const f: PromisifyCustom<string, void>
f[custom] = str => Promise.resolve()
ããããå Žåpromisify.custom
代ããã«äœ¿çšãããcustom
ãåç
§ããããšf[promisify.custom]
ãšã©ãŒã«ãªãElement implicitly has an 'any' type because type 'PromisifyCustom<string, void>' has no index signature.
ïŒ
typescript
import {promisify} from 'util'
interface PromisifyCustom<T, TResult> extends Function {
[promisify.custom](param: T): Promise<TResult>
}
const f: PromisifyCustom<string, void>
f[promisify.custom] = str => Promise.resolve()
é¢æ°ã®promisify.custom
ãã£ãŒã«ãã«å²ãåœãŠããã®ã§ãããïŒäžèšã®åäœãèãããšïŒãããè¡ãå¯äžã®æ¹æ³ã¯é¢æ°ãany
åã«ãã£ã¹ãããããšã§ããããã§ãã
ã·ã³ãã«ãããŒã€ã³ããã¯ã¹ãšããŠèš±å¯ãããŠããªãçç±ãããããŸããã以äžã®ã³ãŒãã¯æ©èœããTypescript 2.8ã§åãå ¥ããããŸãããTypescript2.9ã§ã¯èš±å¯ãããŠããŸããã
/**
* Key can only be number, string or symbol
* */
export class SimpleMapMap<K extends PropertyKey, V> {
private o: { [k: string ]: V } = {};
public has (k: K): boolean {
return k in this.o;
}
public get (k: K): V {
return this.o[k as PropertyKey];
}
public set (k: K, v: V) {
this.o[k as PropertyKey] = v;
}
public getMap (k: K): V {
if (k in this.o) {
return this.o[k as PropertyKey];
}
const res = new SimpleMapMap<K, V>();
this.o[k as PropertyKey] = res as any as V;
return res as any as V;
}
public clear () {
this.o = {};
}
}
ç§ã¯ä»¥äžãè©ŠããŸããããããã¯ç§ã«ãšã£ãŠãããæ£ãããã§ãããTypescriptã³ã³ãã€ã©ã®äž¡æ¹ã®ããŒãžã§ã³ã§åãå ¥ããããŸãã
/**
* Key can only be number, string or symbol
* */
export class SimpleMapMap<K extends PropertyKey, V> {
private o: { [k: K ]: V } = {};
public has (k: K): boolean {
return k in this.o;
}
public get (k: K): V {
return this.o[k];
}
public set (k: K, v: V) {
this.o[k] = v;
}
public getMap (k: K): V {
if (k in this.o) {
return this.o[k];
}
const res = new SimpleMapMap<K, V>();
this.o[k as PropertyKey] = res as any as V;
return res as any as V;
}
public clear () {
this.o = {};
}
}
ãã®ãã±ããã®ã¹ããŒã¿ã¹ã¯ãææ¡ããŠããã®ãæãŸããåäœã§ããããšã瀺ããŠããŸãããã³ã¢ããŒã ã¯çŸæç¹ã§ã¯ããã®æ©èœæ¡åŒµãè¿œå ããããã®ãªãœãŒã¹ãã³ãããããŠããããã³ãã¥ããã£ã«å ¬éããŠå¯ŸåŠããŠããŸãã
@beenotungããã¯çæ³çãªè§£æ±ºçã§ã¯ãããŸããããæçš¿ããã¯ã©ã¹ããã®ãããªåäœãå¿ èŠãšããå¯äžã®å Žæã§ãããšä»®å®ãããšãã¯ã©ã¹å ã§å®å šã§ãªããã£ã¹ããè¡ãããšãã§ããŸãããã¯ã©ã¹ãšã¡ãœããã®ã·ã°ããã£ãåãã«
/**
* Key can only be number, string or symbol
* */
export class SimpleMapMap<K extends PropertyKey, V> {
private o: { [k: string]: V } = {};
public has(k: K): boolean {
return k in this.o;
}
public get(k: K): V {
return this.o[k as any];
}
public set(k: K, v: V) {
this.o[k as any] = v;
}
public getMap(k: K): V {
if (k in this.o) {
return this.o[k as any];
}
const res = new SimpleMapMap<K, V>();
this.o[k as any] = res as any as V;
return res as any as V;
}
public clear() {
this.o = {};
}
}
眲åã¯åãã§ããããããã®ã¯ã©ã¹ã䜿çšãããã³ã«ãåã®æ€èšŒãæ£ããé©çšããããã®åé¡ã解決ããããããã®ã¯ã©ã¹ãå€æŽããã ãã§æžã¿ãŸãïŒã³ã³ã·ã¥ãŒããŒã«å¯ŸããŠééçã«ãªããŸãïŒã
ã³ã³ã·ã¥ãŒããŒã®äŸã¯æ¬¡ã®ãããªãã®ã§ãïŒãã®åé¡ãä¿®æ£ãããå Žåãã³ãŒããå€æŽããå¿ èŠã¯ãããŸããïŒã
const s1 = Symbol(1);
const s2 = Symbol(2);
let m = new SimpleMapMap<symbol, number>()
m.set(s1, 1);
m.set(s2, 2);
m.get(s1);
m.get(1); //error
Typescript 3.0.1ãããã«åãŸããŸããã
symbol
ãåãå
¥ããã¬ã³ãŒãã欲ããã®ã§ãããTSã§ã¯èš±å¯ãããŸããã
ãã®å·ãçºè¡ãããŠãã3ã5幎ã«ãªããŸãããä»ããã·ã³ãã«ãããã ããŸããð
ç®èãªããšã«ãTSã¯ããèªäœãšççŸããŠããŸãã
TSã¯keyof any = number | string | symbol
ãŸãã
ããããããªããrecord[symbol]
TSã¯èšãããšãæåŠããŸã
_Type'symbol 'ã¯ã€ã³ãã¯ãµãŒãšããŠäœ¿çšã§ããŸãã_ã
ãããç§ã¯æ²ããããšã«ãã°ããããã«èŠããã§ããŸãããã®ãããã¯ã«é¢ããç§ã®ææ°ã®è³ªåïŒ
@RyanCavanaugh @DanielRosenwasser @mhegazyæŽæ°ã¯ãããŸããïŒ ãã®å·ã¯4æ³ã®èªçæ¥ãè¿ã¥ããŠããŸãã
誰ããç§ãæ£ããæ¹åã«åããããšãã§ããã°ãç§ã¯ããããã£ãŠã¿ãããšãã§ããŸãã äžèŽãããã¹ããããå Žåã¯ãããã«è¯ãã§ãã
@ jhpratt ïŒ26797ã«PRããããŸãïŒããç¥ãããŠããã·ã³ãã«ã«é¢ããèŠåã«æ³šæããŠãã ããïŒã ïŒ28581ã«ããã«é¢ããæè¿ã®èšèšäŒè°ã®ã¡ã¢ããããŸãïŒãã ããããã«ã¯è§£æ±ºçã¯èšé²ãããŠããŸããïŒã ãã®PRãããã§ä¿çãããŠãŸãã ããã¯ããªã³ãž/圱é¿ã®å°ãªãåé¡ãšèŠãªãããŠããããã§ãã®ã§ãPRãžã®è³æ祚ãå¢ããããšã§åé¡ã®ç¥å床ãäžããããšãã§ãããããããŸããã
@yortusã«æè¬ããŸãã ç§ã¯ã©ã€ã¢ã³ã«ãPRããŸã 3.2ã§èšç»ãããŠãããã©ããå°ããŸãããããã¯ããã€ã«ã¹ããŒã³ã«ãã£ãŠç€ºãããŠããŸãã ããŸãããã°ãããã¯äºå®ã§ãããããã¯è§£æ±ºãããã§ãããïŒ
@yortusãææããPRã¯å€§ããªå€åã®ããã§ããã
ãã®ãã°ã®ä¿®æ£ã¯éåžžã«ãã€ããŒãªãã®ã§ã¯ãããŸãããïŒ ããšãã°ãæ¡ä»¶ãã§ãã¯ã«orã¹ããŒãã¡ã³ããè¿œå ããŸãã
ïŒå€æŽããå Žæã¯ãŸã èŠã€ãããŸãããïŒ
ããã®äžæçãªè§£æ±ºçhttps://github.com/Microsoft/TypeScript/issues/24587#issuecomment-412287117 ãã¡ãã£ãšéãã§ãããä»äºãæãéã
const DEFAULT_LEVEL: string = Symbol("__default__") as any;
å¥ã®https://github.com/Microsoft/TypeScript/issues/24587#issuecomment-460650063 ããªã³ã¿ãŒh8 any
const ItemId: string = Symbol('Item.Id') as unknown as string;
type Item = Record<string, string>;
const shoes: Item = {
name: 'whatever',
}
shoes[ItemId] = 'randomlygeneratedstring'; // no error
{ name: 'whatever', [Symbol(Item.Id)]: 'randomlygeneratedstring' }
ã·ã³ãã«ã䜿çšããéã«æ°ä»ããèœãšãç©Žã®1ã€ã¯ãchild_processã¢ãžã¥ãŒã«ãå«ããããžã§ã¯ããããå Žåã§ããã¯ãã2ã€ã®ããã»ã¹éã§ã¿ã€ã/åæå/ã€ã³ã¿ãŒãã§ã€ã¹ãå ±æã§ããŸãããã·ã³ãã«ã¯å ±æã§ããŸããã
ããã解決ããããšã¯æ¬åœã«çŽ æŽãããããšã§ãããã·ã³ãã«ã¯ããŒãæ±æããã«ãªããžã§ã¯ãã远跡ããããã/ã»ããã䜿çšããå¿ èŠããªããšããç¹ã§éåžžã«åªããŠããŸããããã«ãè¿å¹Žã®ãã³ãããŒã¯ã§ã¯ãã·ã³ãã«ãžã®ã¢ã¯ã»ã¹ã¯æååãžã®ã¢ã¯ã»ã¹ãšåããããé«éã§ããããšã瀺ãããŠããŸãã /æ°åããŒ
ç·šéïŒãã®ã¢ãããŒãã¯Record<X,Y>
ã®ã¿æ©èœãã Interfaces
ã // @ts-ignore
ã¯ãŸã æ§æçã«æ£ãããJSã«é©åã«ã³ã³ãã€ã«ããããããä»ã®ãšãã
ãã ããã·ã³ãã«ãå«ãè¡ã§// @ts-ignore
ã䜿çšããå Žåãå®éã«ã¯ãã®ã·ã³ãã«ã®ã¿ã€ããæåã§æå®ããããšãå¯èœã§ãïŒãããŠåœ¹ç«ã¡ãŸãïŒã VSCodeã¯ãŸã ãããæŸã£ãŠããŸãã
const id = Symbol('ID');
interface User {
name: string;
age: number;
}
const alice: User = {
name: 'alice',
age: 25,
};
// @ts-ignore
alice[id] = 'maybeSomeUUIDv4String';
// ...
// then somewhere, when you need this User's id
// @ts-ignore
const id: string = alice[id];
console.log(id); // here you can hover on id and it will say it's a string
誰ãããããä¿®æ£ããããã«äœããå§ãããã©ããã¯ããããŸããããããã§ãªãå Žåã¯ãç§ã¯ä»æã£ãŠããŸãã
ããããç§ã®æéã¯éãããŠãããTypescriptã®ãœãŒã¹ã«ã€ããŠã®ç¥èã¯ãããŸããã ãã©ãŒã¯ïŒhttps://github.com/Neonit/TypeScriptïŒãäœæããŸãããããã«ãªã¯ãšã¹ãã¯ãŸã ãããŸãããããã¯ãæªå®æã®ïŒïŒïŒå€æŽã§éçºè ãèåŸ ããããªãããã§ãã ã¿ããªã«ç§ã®ãã©ãŒã¯ã«ã§ããããšãå¯ä»ããŠããããããšæããŸãã ãã®æã¯æçµçã«PRãåºããŸãã
ãããŸã§ã®ãšãããã€ã³ã¿ãŒãã§ã€ã¹ã®ã€ã³ããã¯ã¹ã¿ã€ãã®å¶éãä¿®æ£ããæ¹æ³ãèŠã€ããŸããã ãã以äžãããã©ããã¯ããããŸããã TS 3.4ã§ã¯ãä¿®æ£ãªãã§ã·ã³ãã«ã䜿çšããŠãªããžã§ã¯ãã«ã€ã³ããã¯ã¹ãä»ããããšãã§ããŸããã ïŒ https://www.typescriptlang.org/play/#src = constïŒ 20oïŒ 20ïŒ 3DïŒ 20ïŒ 7BïŒ 7DïŒ 3BïŒ 0DïŒ 0AconstïŒ 20sïŒ 20ïŒ 3DïŒ 20SymbolïŒ 's'ïŒïŒ 3B ïŒ 0DïŒ 0AïŒ 0DïŒ 0AoïŒ 5BsïŒ 5DïŒ 20ïŒ 3DïŒ 20123ïŒ 3BïŒ
ç§ãèŠã€ãããã®ã確èªããããã«ç§ã®ã³ããããèŠãŠãã ããïŒ https ïŒ
è¡æ¹äžæïŒ
ãããäœå¹ŽãåŸ ã£ãåŸãããããç©äºãå§ãŸãããšãé¡ã£ãŠããŸãã
ä¿®æ£ã¯è¯ãããã§ãã TypeScriptéçºè ã¯ãããèŠãããšãã§ããŸããïŒ
ããã«ã¡ã¯ãããã«ã€ããŠäœãé²å±ã¯ãããŸããïŒ
ããã«ã€ããŠSOã¹ã¬ãããéãããšããã§ãïŒ https ïŒ
ãªããããäžå¯èœãªã®ã§ããïŒ symbol
number
ãããªå¥ã®ããªããã£ãåã§ã¯ãããŸãã-ã§ã¯ããªãéããããã®ã§ããããïŒ
ããã«ã¡ã¯ãããã«ã€ããŠäœãé²å±ã¯ãããŸããïŒ
5幎ãçµã¡ãŸããïŒ
C ++ãã¯ããŒãžã£ãååŸããã®ã«ã©ããããã®æéãããã£ãããä¿¡ããã€ããã¯ãããŸããð²
ç¬ãã§ã¢ã§ãããC ++ã¯ã¯ããŒãžã£ãæã€èšèªã®ã¹ãŒããŒã»ãããšããŠããèªäœãããŒã±ãã£ã³ã°ããŠããŸãã:-p
@ljharbã¯ãã®éŠ¬ã殎ãç¶ããŸããããã¯ãŸã ããããããŠããŸãð
æ°ããã©ã³ã¿ã€ã ãã¿ãŒã²ããã«ããŠãã人ã¯ã Map
䜿çšããŠã¿ãŸãããïŒ å€ãã®éçºè
ãMap
ãååšããããšãç¥ããªãããšãéžè©±çã«ããã£ãã®ã§ãç§ãèŠéããŠããå¥ã®ã·ããªãªããããã©ããç¥ãããã§ãã
let m = new Map<symbol, number>();
let s = Symbol("arbitrary symbol!");
m.set(s, 1000);
let a = m.get(s);
ããããšãªããžã§ã¯ãã«ã¯ç°ãªããŠãŒã¹ã±ãŒã¹ããããŸãã
@DanielRosenwasserã®ããç¥ãããã·ã³ãã«ããããã³ã«ãšããŠäœ¿çšãããŸãã ããšãã°ãMapããŒãSymbol.match
å Žåããªããžã§ã¯ãã¯æ£èŠè¡šçŸã®ããã«ã¯ãªããŸããïŒãŸããTSçµã¿èŸŒã¿ãæ瀺çã«äœ¿çšããªããŠãããªããžã§ã¯ããå埩å¯èœã«ããããã«Symbol.iterable
ããŒãå¿
èŠã«ãªãå ŽåããããŸãïŒãå埩å¯èœãªã¿ã€ãïŒã
ã»ãŒ5幎ïŒ
ãã®æ©èœãå®è£ ããŠãã ãããã³ãŒããæ£åžžã«èšè¿°ã§ããŸããã
åå è ã¯ãŠãŒã¹ã±ãŒã¹ã§å®éã®äŸãæäŸã§ããŸããïŒ
ãããã³ã«ã®äŸãšããããä»æ¥äžå¯èœãªçç±ãããããŸããã
ãããStringConvertible
äŸã§ã
const intoString = Symbol("intoString")
/**
* Something that can be converted into a string.
*/
interface StringConvertible {
[intoString](): string;
}
/**
* Something that is adorable.
*/
class Dog implements StringConvertible {
[intoString](): string {
return "RUFF RUFF";
}
}
/**
* <strong i="9">@see</strong> {https://twitter.com/drosenwasser/status/1102337805336768513}
*/
class FontDog implements StringConvertible {
[intoString](): string {
return "WOFF WOFF";
}
}
console.log(new Dog()[intoString]())
console.log(new FontDog()[intoString]())
Mappable
ãŸãã¯Functor
äŸã次ã«ç€ºããŸãïŒé«éåã³ã³ã¹ãã©ã¯ã¿ãŒã®æ¬ åŠã¯å¥ãšããŠïŒïŒ
const map = Symbol("map")
interface Mappable<T> {
[map]<U>(f: (x: T) => U): Mappable<U>
}
class MyCoolArray<T> extends Array<T> implements Mappable<T> {
[map]<U>(f: (x: T) => U) {
return this.map(f) as MyCoolArray<U>;
}
}
@DanielRosenwasserã¯ããã¹ãŠã®ãªããžã§ã¯ãã«ã€ã³ã¿ãŒãã§ã€ã¹ãããããã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã§ããããäºåã«ããã£ãŠãããšæ³å®ããŠããããã§ãã æåŸã®äŸã䜿çšãããšãããšãã°ã map
ãä»»æã®javascriptãªããžã§ã¯ãïŒãŸãã¯ãå°ãªããšããä»»æã®ã·ã³ãã«ãè¿œå ã§ããã¿ã€ãã®ãªããžã§ã¯ãïŒã«ã€ã³ã¹ããŒã«ã§ããã¯ãã§ããããã«ããããããå¯èœã«ãªããŸãã
äºåŸã«ããããã£ïŒã·ã³ãã«ãã©ããïŒããªããžã§ã¯ãã«ã€ã³ã¹ããŒã«ããããšã¯ãå¥ã®æ©èœèŠæ±ïŒãæ¡åŒµããããã£ããŸãã¯ãæ¡åŒµã¿ã€ãããšåŒã°ããããšãå€ãïŒã®äžéšã§ãã
ããããªããã°ãã·ã³ãã«ã€ã³ããã¯ã¹çœ²åã«å¿
èŠãªã¿ã€ãã¯ãTypeScriptãŠãŒã¶ãŒãšããŠã¯ã»ãšãã©æäŸãããŸããããïŒ ç§ãæ£ããç解ããŠããã°ãçš®é¡ã¯ã®ãããªãã®ã«ããå¿
èŠããããŸãunknown
ãŸãã¯ã¡ããã©any
ããæçšã§ããããšã
interface SymbolIndexable {
[prop: symbol]: any; // ?
}
ãããã³ã«ã®å Žåãããã¯äžè¬çã«é¢æ°ã§ããã確ãã«ãããã¯unknown
ã§ããå¯èœæ§ããããŸãã
å¿
èŠãªã®ã¯type O = { [k: string]: unknown }
ã«çžåœããèšå·ïŒããã³bigintïŒãªã®ã§ãåã·ã¹ãã ã§å®éã®JSãªããžã§ã¯ãïŒä»»æã®çš®é¡ã®ããŒãæã€ããšãã§ãããã®ïŒãè¡šãããšãã§ããŸãã åŸã§å¿
èŠã«å¿ããŠçµã蟌ãããšãã§ããŸãããJSãªããžã§ã¯ãã®åºæ¬ã¿ã€ãã¯åºæ¬çã«{ [k: string | bigint | symbol | number]: unknown }
ã«ãªããŸãã
ããã @ DanielRosenwasserãã€ã³ãã衚瀺ãããŠãããšæããŸãã ç§ã¯çŸåšã次ã®ãããªã€ã³ã¿ãŒãã§ãŒã¹ãæã€ã³ãŒããæã£ãŠããŸãïŒ
export interface Environment<T> {
[Default](tag: string): Intrinsic<T>;
[Text]?(text: string): string;
[tag: string]: Intrinsic<T>;
// TODO: allow symbol index parameters when typescript gets its shit together
// [tag: symbol]: Intrinsic<T>;
}
ããã§ã Intrinsic<T>
ã¯é¢æ°åã§ãããéçºè
ãæååãšåæ§ã®ç°å¢ã§ç¬èªã®ã·ã³ãã«ããããã£ãå®çŸ©ã§ããããã«ãããã®ã§ããã [Symbol.iterator]
ã [Symbol.species]
ãŸãã¯ã«ã¹ã¿ã ã·ã³ãã«ããããã£ãä»»æã®ã€ã³ã¿ãŒãã§ã€ã¹ã«èšå®ãããšãã·ã³ãã«ä»ãã®ã€ã³ããã¯ã¹çœ²åã«ããããããã®ããããã£ãå®è£
ãããªããžã§ã¯ãã誀ã£ãŠå¶éãããŸãã
ã€ãŸããã·ã³ãã«ã«ããã€ã³ããã¯ã¹ä»ãã®å€åãany
ãããå
·äœçã«ããããšã¯ã§ããªããšããããšã§ããïŒ ãããå¯èœã«ããããã«ãã©ããããããunique symbol
ãšsymbol
åºå¥ã䜿çšã§ããŸããïŒ ã€ã³ããã¯ã¹çœ²åãéåžžã®ã·ã³ãã«ã®ããã©ã«ãã«ããäžæã®/æ¢ç¥ã®ã·ã³ãã«ãã€ã³ããã¯ã¹ã¿ã€ãããªãŒããŒã©ã€ãã§ããããã«ããããšãã§ããŸããïŒ ã¿ã€ãã»ãŒãã§ãªããŠããã·ã³ãã«ã€ã³ããã¯ã¹ã«ãã£ãŠããããã£ãä»»æã«ååŸ/èšå®ã§ãããšäŸ¿å©ã§ãã
å¥ã®æ¹æ³ã¯ããŠãŒã¶ãŒã«ã·ã³ãã«ããããã£ã䜿çšããŠç°å¢ã€ã³ã¿ãŒãã§ã€ã¹ãæ¡åŒµãããããšã§ããããŠãŒã¶ãŒããªããžã§ã¯ãã«äœã§ãå ¥åã§ããéããããã¯è¿œå ã®ã¿ã€ãã®å®å šæ§ãæäŸããŸããã
@DanielRosenwasserããã«ç§ã®çç£ã³ãŒãã®æ¬åœã®äŸã å€ãã®å Žæã§ããããšããŠåå©çšãããã¢ãã ã®ããŒïŒãã¡ã€ã³åãããæ©èœïŒãåãå ¥ããå Žåãããç¶æ ã çŸåšãã·ã³ãã«ãµããŒããè¿œå ããå¿ èŠããããŸãããå€ãã®ãšã©ãŒãçºçããŸãã
ãšã«ãããçŸåšã®åäœã¯ééã£ãŠããESæšæºãšäºææ§ããããŸããã
ã·ã³ãã«ã¿ã€ãã«é¢ããŠç§ãæã£ãŠãããã1ã€ã®æ·±å€ã®èãã ãªãããã¯ãšã©ãŒã§ã¯ãªãã®ã§ããïŒ
const foo = {
[Symbol.iterator]: 1,
}
JSã¯ããã¹ãŠã®Symbol.iterator
ããããã£ãã€ãã¬ãŒã¿ãè¿ãé¢æ°ã§ãããšæ³å®ããŠããããã®ãªããžã§ã¯ããããŸããŸãªå Žæã§æž¡ããããšãå€ãã®ã³ãŒããç ŽæããŸãã ãã¹ãŠã®ãªããžã§ã¯ãã®ã·ã³ãã«ããããã£ãã°ããŒãã«ã«å®çŸ©ããæ¹æ³ãããã°ãç¹å®ã®ã·ã³ãã«ã€ã³ããã¯ã¹çœ²åãèš±å¯ãããšåæã«ãã°ããŒãã«ãªãŒããŒã©ã€ããèš±å¯ããããšãã§ããŸãã ã¿ã€ãã»ãŒãã§ããïŒ
ãŸããããã§ãŠãŒã¹ã±ãŒã¹ãå¿ èŠã«ãªãçç±ãããããŸããã ããã¯ES6ã®éäºææ§ã§ãããES6ãã©ããããèšèªã«ã¯ååšããªãã¯ãã§ãã
éå»ã«ãããããã®ã¹ã¬ããã§ä¿®æ£ããæ¹æ³ã«ã€ããŠã®èª¿æ»çµæãæçš¿ããŸããããã®ã³ãŒãã«éèŠãªãã§ãã¯ãæ©èœããªãå Žåã¯ããã®èª¬æãç¶ãããããã³ãŒãããŒã¹ã«çµ±åããæ¹ãæéãããããšã¯æããŸããã
Typescriptã®ãã¹ããã¬ãŒã ã¯ãŒã¯ãèŠä»¶ãããããããã¹ãŠã®å Žåã«ãããæ©èœãããããã«ããŸããŸãªãã¡ã€ã«ãå€æŽããå¿ èŠããããã©ããããããªãããããã«ãªã¯ãšã¹ããå®è¡ããŸããã§ããã
ãããã£ãŠãããã§èªã¿åããšæžã蟌ã¿ã«æéãè²»ããç¶ããåã«ãæ©èœã®è¿œå ã«ãããæéãççž®ããããã©ããã確èªããŠãã ããã Typescriptã«ããããšã«ã€ããŠèª°ããäžæºãèšããšã¯æããŸããã
ãããšã¯å¥ã«ãäžè¬çãªäœ¿çšäŸã¯ãå€ãä»»æã®ã·ã³ãã«ã«ãããããå Žåã§ãã ãŸãã¯ãåæå®ãããŠããªãES6ã³ãŒããšã®äºææ§ã®ããã
ããã圹ç«ã€ãšæãå Žæã®äŸã次ã«ç€ºããŸãïŒ https ïŒ eventName
ã¯èšå·ãŸãã¯æååã§ããå¯èœæ§ãããããã次ã®ããã«èšããããšæããŸãã
type EventsConfiguration = { [eventName: string | Symbol]: (...args: any[]) => void }
æåã®è¡ã«ã
ããããç§ã¯ãããã©ã®ããã«è¡ãã¹ããã«ã€ããŠäœãã誀解ããŠãããããããŸããã
åçŽãªãŠãŒã¹ã±ãŒã¹ã¯ãèŠçãªãã«ã¯å®è¡ã§ããŸããã
type Dict<T> = {
[key in PropertyKey]: T;
};
function dict<T>() {
return Object.create(null) as Dict<T>;
}
const has: <T>(dict: Dict<T>, key: PropertyKey) => boolean = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
function forEach<T>(dict: Dict<T>, callbackfn: (value: T, key: string | symbol, dict: Dict<T>) => void, thisArg?: any) {
for (const key in dict)
if (has(dict, key))
callbackfn.call(thisArg, dict[key], key, dict);
const symbols = Object.getOwnPropertySymbols(dict);
for (let i = 0; i < symbols.length; i++) {
const sym = symbols[i];
callbackfn.call(thisArg, dict[sym], sym, dict); // err
}
}
const d = dict<boolean>();
const sym = Symbol('sym');
const bi = 9007199254740991n;
d[1] = true;
d['x'] = true;
d[sym] = false; // definitely PITA
d[bi] = false; // another PITA
forEach(d, (value, key) => console.log(key, value));
ãŸããããã§ãŠãŒã¹ã±ãŒã¹ãå¿ èŠã«ãªãçç±ãããããŸããã
@neonitããã«å¯ŸåŠããããã®PRããããŸãããç§ã®ç解ã§ã¯ããã®æ©èœãä»ã®åã·ã¹ãã ãšã©ã®ããã«çžäºäœçšãããã«ã€ããŠåŸ®åŠãªåé¡ããããŸãã ããã«å¯Ÿãã解決çããªãã®ã§ãç§ããŠãŒã¹ã±ãŒã¹ãæ±ããçç±ã¯ãç§ãã¡ãæããã¹ãŠã®æ©èœã«äžåºŠã«åãçµã/éäžããããšãã§ããªãããã§ã-ãããã£ãŠããŠãŒã¹ã±ãŒã¹ã¯ãé·æãå«ãããäœæ¥ãæ£åœåããå¿ èŠããããŸãæ©èœã®ã¡ã³ããã³ã¹ã
å®éãã»ãšãã©ã®äººãæ³åããŠãããŠãŒã¹ã±ãŒã¹ã¯ãæ³åããŠããã»ã©ç°¡åã«ã¯è§£æ±ºãããªãããã§ãïŒ @brainkimã®åçã¯ãã¡ãhttps://github.com/microsoft/TypeScript/issues/1863#issuecomment-574550587ãåç §ïŒããŸãã¯ãã·ã³ãã«ããããã£ïŒhttps://github.com/microsoft/TypeScript/issues/1863#issuecomment-574538121ïŒãŸãã¯ãããïŒhttps://github.com/microsoft/TypeScript/issues/1863ïŒãä»ããŠåæ§ã«ããŸã解決ãããããšïŒissuecomment-572733050ïŒã
@ Tyler-Murphyã¯ãå¶çŽãèšè¿°ã§ããªããšããç¹ã§ãããã§æè¯ã®äŸã瀺ãããšæããŸããããã¯ãã·ã³ãã«ããµããŒãããã¿ã€ãã»ãŒããªã€ãã³ããšããã¿ãŒã®ãããªãã®ã«éåžžã«åœ¹ç«ã¡ãŸãã
ãããã£ãŠãããã§èªã¿åããšæžã蟌ã¿ã«æéãè²»ããç¶ããåã«ãæ©èœã®è¿œå ã«ãããæéãççž®ããããã©ããã確èªããŠãã ããã Typescriptã«ããããšã«ã€ããŠèª°ããäžæºãèšããšã¯æããŸããã
ãããžã§ã¯ããç¶æããå¿ èŠããªãå Žåãããã¯åžžã«èšããããã§ãïŒ ðããã¯ããªãã«ãšã£ãŠåœ¹ç«ã€ããšã ãšç解ããŠããŸããããããå°éããŠããã ããã°å¹žãã§ãã
ããã¯ES6ã®éäºææ§ã§ã
TypeScriptã¯å®è¡äžå¯èœã§ãããããç°¡åã«å ¥åã§ããªãæ§é ããããããããŸãã ãããäžå¯èœã ãšèšã£ãŠããããã§ã¯ãããŸããããããããã®åé¡ãçµã¿ç«ãŠãé©åãªæ¹æ³ã ãšã¯æããŸããã
ãããã£ãŠãã€ã³ããã¯ã¹çœ²åãšããŠã·ã³ãã«ããŒãè¿œå ã§ããªãã®ã¯ãç¬èªã®åæå®ãå¿ èŠãšããã°ããŒãã«ã§ããç¥ãããŠããã·ã³ãã«ããããã·ã³ãã«ã€ã³ããã¯ã¹ã¿ã€ããå¿ ç¶çã«è¡çªãããšããäºå®ã«èµ·å ããŠããããã§ãã 解決çãšããŠããã¹ãŠã®æ¢ç¥ã®ã·ã³ãã«ãè¡šãã°ããŒãã«ã¢ãžã¥ãŒã«/ã€ã³ã¿ãŒãã§ã€ã¹ãããå Žåã¯ã©ããªããŸããïŒ
const Answerable = Symbol.for("Answerable");
declare global {
interface KnownSymbols {
[Answerable](): string | number;
}
}
interface MyObject {
[name: symbol]: boolean;
}
const MySymbol = Symbol.for("MySymbol");
const obj: MyObject = {
[MySymbol]: true,
};
obj[Answerable] = () => "42";
ã°ããŒãã«KnownSymbols
ã€ã³ã¿ãŒãã§ã€ã¹ã§è¿œå ã®ããããã£ã宣èšããããšã«ããããã¹ãŠã®ãªããžã§ã¯ãã«ãã®ã·ã³ãã«ã§ã€ã³ããã¯ã¹ãä»ããããšãã§ããããããã£ã®å€ãæªå®çŸ©/å€åã«å¶éã§ããŸãã ããã¯ãtypescriptãES6ã«ãã£ãŠæäŸãããããç¥ãããèšå·ã®åä»ããæäŸã§ããããã«ããããšã§ãããã«äŸ¡å€ãæäŸããŸãã ã€ãã¬ãŒã¿ãè¿ãé¢æ°ã§ã¯ãªããªããžã§ã¯ãã«Symbol.iterator
ããããã£ãè¿œå ãããšãæããã«ãšã©ãŒã«ãªãã¯ãã§ãããçŸåštypescriptã«ãããã®ã§ã¯ãããŸããã ãŸããæ¢åã®ãªããžã§ã¯ãã«æ¢ç¥ã®ã·ã³ãã«ããããã£ãè¿œå ããã®ãã¯ããã«ç°¡åã«ãªããŸãã
ãã®ã°ããŒãã«ã¢ãžã¥ãŒã«ã®äœ¿çšã«ãããã·ã³ãã«ãä»»æã®ããŒãšããŠã䜿çšã§ããããã«ãªãããããã£ãŠã€ã³ããã¯ã¹çœ²åã§äœ¿çšã§ããããã«ãªããŸãã ã°ããŒãã«ãªæ¢ç¥ã®ã·ã³ãã«ããããã£ãããŒã«ã«ã€ã³ããã¯ã¹ã·ã°ããã£ã¿ã€ããããåªå ããã ãã§ãã
ãã®ææ¡ãå®è£ ããããšã§ãã€ã³ããã¯ã¹çœ²åã¿ã€ããåé²ãããããšãã§ããŸããïŒ
åã ã®ãŠãŒã¹ã±ãŒã¹ã¯é¢ä¿ãããŸããã 倧éã®JavaScriptã®å Žåã¯ãTSå®çŸ©ã§è¡šçŸã§ããå¿ èŠããããŸãã
ããããç§ã®ç解ã§ã¯ãæ©èœãä»ã®åã·ã¹ãã ãšã©ã®ããã«çžäºäœçšãããã«ã¯åŸ®åŠãªåé¡ããããŸã
æ£ç¢ºã«ã¯ããã€ã³ããã¯ã¹ã·ã°ããã£ãå éšçã«ã©ã®ããã«æ©èœãããããªãã¡ã¯ã¿ãªã³ã°ããã®ã§ãæããã倧ããªå€æŽã§ãããã€ã³ããã¯ã¹ã·ã°ããã£ããã³ãã¬ãŒãå€æ°ã䜿çšããªãããããããã¿ã€ããšã©ã®ããã«ç°ãªããããŸãã¯ç°ãªãã¹ããã«ã€ããŠã®åé¡ãçºçããŸããã®ãããªãã®ã§ãã
ããã¯äž»ã«ãã¯ããŒãºãã¿ã€ããšãªãŒãã³ã¿ã€ãã®èªèã«å€±æããæ¹æ³ã«ã€ããŠã®è°è«ã«ã€ãªãããŸããã ãã®ã³ã³ããã¹ãã§ã¯ããéãããã¿ã€ãã¯ãå€ãæ¡åŒµã§ããªãæéã®ããŒã»ãããæã€ã¿ã€ãã«ãªããŸãã å¿
èŠã«å¿ããŠãããçš®ã®æ£ç¢ºãªã¿ã€ãã®ããŒã äžæ¹ããã®ã³ã³ããã¹ãã§ã®ããªãŒãã³ãã¿ã€ãã¯ããµãã¿ã€ãåããããšãããå€ãã®ããŒãè¿œå ã§ããã¿ã€ãã§ãïŒçŸåšã®ãµãã¿ã€ãåã«ãŒã«ã§ã¯ãéåžžã«æ瀺çã«ã€ã³ããã¯ã¹çœ²åãããã¿ã€ããé€ããŠãã»ãšãã©ãã¹ãŠã®ã¿ã€ãããããŸãïŒã ã ã€ã³ããã¯ã¹ã·ã°ããã£ã¯ãªãŒãã³ã¿ã€ããäœæããããšãæå³ããŸãããããããããã¿ã€ãã¯ãã¯ããŒãºãã¿ã€ãã§åäœããŠãããã®ããã«å€§ããé¢é£ããŠããŸãã ã»ãšãã©ã®ã³ãŒãã¯ãå®éã«ã¯ãéãããªããžã§ã¯ãã¿ã€ããšäºææ§ã®ããæ§é ã§èšè¿°ãããŠãããããããã¯_éåžž_ååã«æ©èœããŸãã ãããã flow
ïŒéãããªããžã§ã¯ãã¿ã€ããšéãããªããžã§ã¯ãã¿ã€ãã®æ瀺çãªæ§æãæã€ïŒãããã©ã«ãã§éãããªããžã§ã¯ãã¿ã€ãã«ãªãçç±ã§ãã ããã¯ãäžè¬çãªã€ã³ããã¯ã¹ããŒã§é ã«æµ®ãã³ãŸãã T extends string
å Žåã T
ã¯ãŸããŸãå¹
åºãã¿ã€ãïŒ "a"
ãã"a" | "b"
ããstring
ïŒã§ã€ã³ã¹ã¿ã³ã¹åãããããããªããžã§ã¯ã"a" | "b" | ... (every other possible string)
ããstring
èªäœã«åãæ¿ãããŸã§ããããã¥ãŒã¹ã¯ãŸããŸãå°éåãããŠããŸãã ãããèµ·ãããšãçªç¶ã¿ã€ããéåžžã«ãªãŒãã³ã«ãªããã¢ã¯ã»ã¹ããããã«ãã¹ãŠã®ããããã£ãååšããå¯èœæ§ããããŸãããããšãã°ã空ã®ãªããžã§ã¯ããããã«å²ãåœãŠãããšã¯åæ³ã«ãªããŸãã ãããæ§é çã«èµ·ããããšã§ãããããããããåã®ãžã§ããªãã¯ãé¢é£ä»ãããšãããããç¡èŠããŸã-ãžã§ããªãã¯ã®ããããããåããŒã®string
å¶çŽã¯ããã¹ãŠã®å¯èœãªããŒãååšãããã®ããã«æ¬è³ªçã«é¢é£ä»ããããŸãã ããã¯è«ççã«ã¯ããŒã¿ã€ãã®åçŽãªåæ£ããŒã¹ã®ãã¥ãŒããåŸãããŸãããæ£ããã®ã¯ããŒã_closed_ã¿ã€ãããã®ãã®ã§ããå Žåã®ã¿ã§ãïŒå€ãã®å Žåãã€ã³ããã¯ã¹ã·ã°ããã£ãæã€ã¿ã€ããå®éã«éããããããšã¯ãããŸããïŒïŒã ãããã£ãŠãäžäœäºææ§ãå¿
èŠãªå Žåã¯ã {[x: T]: U}
ã{[_ in T]: U}
ãšåãããã«æ±ãããšã¯ã§ããŸããããã ããäžè¬çã§ãªãå Žåã¯{[_ in T]: U}
ã§ãããããå¿
èŠãªå Žåãé€ããŸãã {[x: T]: U}
ã«ãªããŸããããããããã¿ã€ãã®ããŒã®åæ£ãåŠçããæ¹æ³ã調æŽããŠããªãŒãã³ã¿ã€ãã®ããšããžããé©åã«èæ
®ããŸããããã¯ããšã³ã·ã¹ãã ã«åœ±é¿ãäžããå¯èœæ§ã®ãããããèªäœãèå³æ·±ãå€æŽã§ãã
ããªãïŒããããããã¿ã€ããšã€ã³ããã¯ã¹ã·ã°ããã£ãéåžžã«æ¥è¿ããŠãããããäž¡æ¹ãã©ã®ããã«åŠçãããã«ã€ããŠå€ãã®è³ªåããããŸãããããŸã æºè¶³ã®ããããŸãã¯æ±ºå®çãªçãã¯ãããŸããã
åã ã®ãŠãŒã¹ã±ãŒã¹ã¯é¢ä¿ãããŸããã
ããã¯ãäžå¯§ã«ãçŽç²ãªçæ°ã§ãã ã¿ãŒããŒã·ã§ã³ã§ã¯ããã®åäœãå€æããããã®ãŠãŒã¹ã±ãŒã¹ãªãã§ã人ã ãæãåäœãåããæ©èœãè¿œå ããŠãããã©ãããã©ã®ããã«ç¥ãããšãã§ããŸããïŒ
ç§ãã¡ã¯ãããã®è³ªåãããããšã«ãã£ãŠããã§å°é£ã«ãªãããšã¯ããŠããŸããã ç§ãã¡ã¯æåéãã人ã ãæ±ããŠããããšã確å®ã«å®è¡ããããšããŠããŸãã ãã·ã³ãã«ã䜿çšããã€ã³ããã¯ã¹äœæããšæããããã®ãå®è£ ããå Žåããã®ã¹ã¬ããã®ãŸã£ããåã人ãæ»ã£ãŠããŠãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«å¯Ÿå¿ããŠããªãã£ãããã«å®å šã«ééã£ããšèšã£ãã ãã§ãæ¬åœã«æ®å¿µã§ãã
ããªãã¯ç§ãã¡ã«ç²ç®çã«é£ã¶ããã«é Œãã§ããŸãã ããªãã§ãã ããïŒ é£è¡æ©ã®è¡ãå ãæããŠãã ããïŒ
ç§ã®æªãããšã«ãç§ã¯èªåãäœãæå³ããã®ããããæ確ã«ããããšãã§ããã§ãããã TSãä»ããŠã³ãŒããããæ£ç¢ºã«èšè¿°ããããšããé¡æã§ã¯ãªããå®éã®ã³ãŒãã®ãŠãŒã¹ã±ãŒã¹ãæ£åœåããå¿ èŠããããšäººã ãæããŠããããã«æããŸããã
ãããã£ãŠãç§ããããæ£ããç解ããŠããå Žåãããã¯äž»ã«æ¬¡ã®åé¡ã«é¢ãããã®ã§ãã
const sym = Symbol();
interface Foo
{
[sym]: number;
[s: symbol]: string; // just imagine this would be allowed
}
Foo[sym]
ã¯ãããŸããªåã§ãããããTypescriptã³ã³ãã€ã©ã¯ããã競åãšèŠãªããŸãã æååã«ã€ããŠãåãåé¡ããã§ã«çºçããŠããŸãã
interface Foo
{
['str']: number; // <-- compiler error: not assignable to string index type 'string'
[s: string]: string;
}
ãããæååã€ã³ããã¯ã¹ã§åŠçãããæ¹æ³ã¯ãæååããŒã®äžè¬çãªä»æ§ãããããããã®ã¿ã€ãã«äºææ§ããªãå Žåãç¹å®ã®æååã€ã³ããã¯ã¹ã¯èš±å¯ãããªããšããããšã§ãã
ç§ã¯ECMA2015ã®ãããªæšæºã·ã³ãã«å®çŸ©ããããã®ã·ã³ãã«ã®ããã«ãããã¯ãéåšåé¡ã ãããšæããŸãSymbol.iterator
ä»»æã®ãªããžã§ã¯ãã§äœ¿çšããããšãã§ããŸãã®ã§ãããã©ã«ãã®ã¿ã€ãã³ã°ãæã£ãŠããå¿
èŠããããã 圌ãã¯å¥åŠãªããšã«ãããæããã«æã£ãŠããŸããã å°ãªããšãéã³å Žã§ã¯ãMDNããSymbol.iterator
äŸãå®è¡ããããšã¯ã§ããŸããã
äºåå®çŸ©ãããã·ã³ãã«åãè¿œå ããããšãèšç»ãããŠãããšä»®å®ãããšãäºåå®çŸ©ãããã·ã³ãã«ã€ã³ããã¯ã¹ã«ã¯ãã§ã«äºææ§ã®ãªãåããããå
±éã®äžè¬åãååšã§ããªãããããããå¿
èŠã«ãªããããäžè¬çãª[s: symbol]: SomeType
å®çŸ©ã¯åžžã«ç¡å¹ã«ãªããŸããã»ãšãã©ïŒ/ allïŒïŒã®äºåå®çŸ©ãããã·ã³ãã«ããŒã¯function
ã¿ã€ãã§ããããã function
ã¿ã€ãã«ãªããŸãã
äžè¬çãªã€ã³ããã¯ã¹ã¿ã€ããšç¹å®ã®ã€ã³ããã¯ã¹ã¿ã€ããæ··åšããå Žåã®åé¡ã¯ãã³ã³ãã€ã«æã«äžæãªå€ã§ãªããžã§ã¯ãã«ã€ã³ããã¯ã¹ãä»ããããå Žåã®ã¿ã€ãã®æ±ºå®ã§ãã æååã€ã³ããã¯ã¹ã䜿çšããäžèšã®äŸãæå¹ã§ãããšæ³åãããšã次ã®ããšãå¯èœã«ãªããŸãã
const foo: Foo = {str: 42, a: 'one', b: 'two'};
const input: string = getUserInput();
const value = foo[input];
åãåé¡ãã·ã³ãã«ããŒã«ãåœãŠã¯ãŸããŸãã ã³ã³ãã€ã«æã«value
ã®æ£ç¢ºãªã¿ã€ããå€å¥ããããšã¯äžå¯èœã§ãã ãŠãŒã¶ãŒã'str'
å
¥åãããšã number
ã«ãªããŸãããã以å€ã®å Žåã¯ã string
ïŒå°ãªããšãTypescriptã¯string
ã§ãããšæ³å®ããŸããã undefined
ãªãå¯èœæ§ããããŸãïŒã ãããããã®æ©èœããªãçç±ã§ããïŒ value
ãå®çŸ©ããã®ãã¹ãŠã®å¯èœãªåãå«ãå
±çšäœåïŒãã®å Žåã¯number | string
ïŒãäžããããšã§ããããåé¿ã§ããŸãã
@Neonitãããšãããã¯å®è£ ã®é²è¡ã劚ããåé¡ã§ã¯ãããŸããããããã¯ãŸãã«ç§ãææããããšããŠããåé¡ã®1ã€ã§ã-ããªããããããšããŠããããšã«ãã£ãŠã¯ãã·ã³ãã«ã€ã³ãã¯ãµãŒãçãã§ã¯ãªããããããŸããã
ãã®æ©èœãå®è£ ãããŠããå Žåããã¹ãŠã®ã¿ã€ãããããã®ã·ã³ãã«ã䜿çšããããã§ã¯ãªããããECMAScriptã®çµã¿èŸŒã¿ã·ã³ãã«ãå¿ ããããã¹ãŠãå°ç¡ãã«ããããã§ã¯ãããŸããã ãã ããããç¥ãããŠããã·ã³ãã«ïŒãŸãã¯èªåã§å®çŸ©ããã·ã³ãã«ïŒã䜿çšããŠããããã£ãå®çŸ©ããã¿ã€ãã¯ãã·ã³ãã«ã®ããŸã圹ã«ç«ããªãã€ã³ããã¯ã¹çœ²åã«å¶éãããå¯èœæ§ããããŸãã
ããã¯æ¬åœã«èŠããŠããã¹ãããšã§ããããããããããšããŠäœ¿çšãããããšãã·ã³ãã«ã䜿çšããŠãããã³ã«ãå®è£ ããããã®ãŠãŒã¹ã±ãŒã¹ã¯ãåã·ã¹ãã ã®èŠ³ç¹ããã¯äºææ§ããããŸããã ãããã£ãŠããã®ãããªããšã念é ã«çœ®ããŠããå Žåã¯ãã·ã³ãã«ã€ã³ããã¯ã¹ã®çœ²åã圹ã«ç«ããªãå¯èœæ§ããããæ瀺çãªã·ã³ãã«ããããã£ãŸãã¯ããããä»ããŠããé©åã«æ©èœããå¯èœæ§ããããŸãã
symbol
ããçµã¿èŸŒã¿ã·ã³ãã«ãå·®ãåŒããUserSymbol
ã¿ã€ãã®ãããªãã®ã¯ã©ãã§ããïŒ ã·ã³ãã«ã®æ§è³ªäžãå¶çºçãªè¡çªã
ç·šéïŒããã«ã€ããŠãã£ãšèãããšãããç¥ãããŠããã·ã³ãã«ã¯ãããŸããŸSymbol
ã䜿çšããŠå®è£
ãããæ©åšã§ãã ç®æšããªããžã§ã¯ãã®ã·ãªã¢ã«åãŸãã¯ã€ã³ããã¹ãã¯ã·ã§ã³ã§ãªãéããã³ãŒãã¯ãããã®ã»ã³ããã«ãä»ã®ã·ã³ãã«ãšã¯ç°ãªãæ¹æ³ã§åŠçããsymbol
ã¿ã€ãããããããåé€ãããšããæ±çšãã·ã³ãã«ã䜿çšããïŒã»ãšãã©ã®ïŒã³ãŒããããå®å
šã«ãªãå¯èœæ§
@RyanCavanaughãããç§ã®é£è¡èšç»ã§ãã
ãã®ãããªèšå·ãããããã£ã«äœ¿çšããã·ã¹ãã ããããŸãã
const X = Symbol.for(":ns/name")
const txMap = {
[X]: "fly away with me!"
}
transact(txMap) // what's the index signature here?
ãã®å Žåã txMap
ãtransact
ã®åã·ã°ããã£ã«é©åãããããšæããŸãã ããããç§ã®ç¥ãéããä»æ¥ãããè¡šçŸããããšã¯ã§ããŸããã ç§ã®å Žåã transact
ã¯ãäœãæåŸ
ãã¹ããããããªãã©ã€ãã©ãªã®äžéšã§ãã ç§ã¯ããããã£ã«å¯ŸããŠãã®ãããªããšãããŸãã
// please forgive my tardiness but in essence this is how I'm typing "TxMap" for objects
type TxMapNs = { [ns: string]: TxMapLocal }
type TxMapLocal = { [name: string]: string | TxMapNs } // leaf or non leaf
ã¹ããŒãããtransact
é©åããã¿ã€ãã®ã»ãããçæããããã䜿çšã§ããŸãã ãã®ããã«ç§ã¯ãã®ãããªããšããã宣èšã®ããŒãžã«äŸåããŸãã
interface TxMap = {
[DB_IDENT]: symbol // leaf
[DB_VALUE_TYPE]?: TxMap // not leaf
[DB_CARDINALITY]?: TxMap
}
ããããå°ãªããšãã·ã³ãã«ã®ã€ã³ããã¯ã¹çœ²åã«ãã©ãŒã«ããã¯ã§ããã°ããã®ã§ããã transact
ã ãããã¬ãŒã³ãªJavaScriptãªããžã§ã¯ãã«æž¡ãããããšãæåŸ
ããŠããŸãããã®å Žåãã°ããŒãã«ã·ã³ãã«ã¬ãžã¹ããªã®ã·ã³ãã«ã®ã¿ã䜿çšããŸãã ãã©ã€ããŒãã·ã³ãã«ã¯äœ¿çšããŠããŸããã
ããã¯å°ãèŠçã ãšä»ãå ããŠãããŸãã
const x = Symbol.for(":x");
const y = Symbol.for(":x");
type X = { [x]: string };
type Y = { [y]: string };
const a: X = { [x]: "foo" };
const b: Y = { [x]: "foo" }; // not legal
const c: X = { [y]: "foo" }; // not legal
const d: Y = { [y]: "foo" };
TypeScriptãã Symbol.for
é¢æ°ãä»ããŠäœæãããã·ã³ãã«ãå®éã«åãã§ããããšãç解ã§ããã°ãéåžžã«ãã°ãããã§ãããã
ãããéåžžã«è¿·æã§ãã
function keyword(ns: string, name: string): unique symbol { // not possible, why?
return Symbol.for(":" + ns + "/" + name)
}
const x: unique symbol = keyword("db", "id") // not possible, why?
type X = {
[x]: string // not possible, why?
}
ãã®å°ããªãŠãŒãã£ãªãã£é¢æ°ã§ãã°ããŒãã«ã·ã³ãã«ããŒãã«ã«èŠçŽãé©çšããŸãããã ãã ãã Symbol.for
é¢æ°ã䜿çšããŠäœæãããå Žåã§ãã unique symbol
è¿ãããšã¯ã§ããŸããã TypeScriptãç©äºãè¡ãæ¹æ³ã®ããã«ãç§ã¯ç¹å®ã®è§£æ±ºçãæŸæ£ããããåŸãŸããã ãããã¯æ©èœããŸããã ãããŠãããã¯æ²ããããšã ãšæããŸãã
ESãããã·ã䜿çšããŠãªããžã§ã¯ãããããã·ã§ã©ãããããã¡ã¯ããªé¢æ°ãäœæãããšãã«ãã€ã³ããã¯ã¹å€ãšããŠsymbol
ã圹ç«ã€å¥ã®ãŠãŒã¹ã±ãŒã¹ã«ééããŸããã
ãã®äŸãèŠãŠãã ããïŒ
let original = {
foo: 'a',
bar: 'b',
baz: 1
};
function makeProxy<T extends Object>(source: T) {
return new Proxy(source, {
get: function (target, prop, receiver) {
return target[prop];
}
});
}
let proxied = makeProxy(original);
ProxyConstructor
åã®çœ²åãäžèŽãããã«Object
ã«æ¡åŒµããå¿
èŠããããŸãããæ±çšåŒæ°ã«ããŒãèšå®ãããŠããªãããããšã©ãŒãçºçããŸãã ãããã£ãŠãåã·ã°ããã£ãæ¡åŒµã§ããŸãã
function makeProxy<T extends Object & { [key: string]: any}>(source: T) {
ãããã ProxyHandler
ã®get
ã®2çªç®ã®åŒæ°ïŒ prop
ïŒã¯PropertyKey
åã§ããããããšã©ãŒãçºçããŸããããã¯ããŸããŸPropertyKey
ã
ãããã£ãŠããã®åé¡ã®å¶éã®ãããTypeScriptã§ãããè¡ãæ¹æ³ãããããŸããã
@aaronpowellããªããçŽé¢ããŠããåé¡ã¯äœã§ããïŒ æ£åžžã«åäœããŠããããšãããããŸãã
let original = {
foo: 'a',
bar: 'b',
baz: 1
};
function makeProxy<T extends Object>(source: T) {
return new Proxy(source, {
get: function (target, prop, receiver) {
return target[prop];
}
});
}
let proxied = makeProxy(original);
function assertString(s:string){}
function assertNumber(x:number){}
assertString(proxied.foo); // no problem as string
assertNumber(proxied.baz); // no problem as number
console.log(proxied.foobar); // fails as expected: error TS2339: Property 'foobar' does not exist on type '{ foo: string; bar: string; baz: number; }'.
tsconfig.jsonïŒ
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node",
"target": "es2015"
}
package.jsonïŒ
{
"devDependencies": {
"typescript": "~3.4.5"
}
}
@beenotungéã³å Žã§ãšã©ãŒã衚瀺ãããŸãïŒ
@aaronpowell tsconfig.json
ã®ãcompilerOptionsãã§ãstrictããã©ã°ãæå¹ã«ãããšããšã©ãŒã衚瀺ãããŸãã
ãããã£ãŠãçŸåšã®ããŒãžã§ã³ã®typescriptã³ã³ãã€ã©ã§ã¯ãstrictã¢ãŒãããªãã«ããããã¿ãŒã²ãããany
ãã£ã¹ãããå¿
èŠããããŸã...
ãã¡ããã§ããã any
ãã£ã¹ãã¯å®éã«ã¯çæ³çã§ã¯ãªããå³å¯ã¢ãŒããç¡å¹ã«ãããšãåå®å
šæ§ã®å¶éãç·©åãããã ãã§ãã
ã¡ãã»ãŒãžãèªã次ã®ã解決çãã¯ãããããtypescriptãç¡å¹ã«ãããããšã ãšæããŸãã
äžæçãªè§£æ±ºçãæ¢ãå¿ èŠã¯ãªãããªããããå¿ èŠãªã®ãã説æããå¿ èŠããããŸããã
ããã¯javascriptã®æšæºæ©èœãªã®ã§ãtypescriptã§å¿ èŠã§ãã
@DanielRosenwasserç§ã®ãŠãŒã¹ã±ãŒã¹ã¯ãŸã- ProxyHandler
ã€ã³ã¿ãŒãã§ã€ã¹ãšTypeScriptã®ã«ãŒã«ãäžèŽããŠããªãããããããã·ãã³ãã©ãã©ãããæ£ããå
¥åã§ããŸããã
åé¡ã瀺ãèŠçŽäŸïŒ
const getValue = (target: object, prop: PropertyKey) => target[prop]; // Error
ç§ã®ç¥ãéãããšã©ãŒãåé¿ããªããã PropertyKey
ãåæ³çã«ã¢ã¯ã»ã¹ã§ãããªããžã§ã¯ãã®ã¿ãèš±å¯ããtarget
ã¿ã€ããäœæããããšã¯äžå¯èœã§ãã
ç§ã¯TypeScriptã®åå¿è ãªã®ã§ãæãããªäœããæ¬ ããŠããå Žåã¯ã容赊ãã ããã
å¥ã®ãŠãŒã¹ã±ãŒã¹ïŒåŒã³åºãå
ãç¹å®ã®ã¿ã€ãã®ã¿ã°ä»ãå€ã®ããããæäŸããããã«ããªããžã§ã¯ããªãã©ã«æ§æã®ã³ã³ãã¯ããã®æ©æµãåããæ¹æ³ã§ïŒååã®è¡çªãåé¿ããªããïŒã¿ã€ã{[tag: symbol]: SomeSpecificType}
ãäœæããããšããŠããŸãããã¬ãŒã³æååãã¿ã°ãšããŠäœ¿çšãããªã¹ã¯ïŒã
å¥ã®ãŠãŒã¹ã±ãŒã¹ïŒãªããžã§ã¯ããã·ã³ãã«ãæååã®äž¡æ¹ã®åæå¯èœãªãã¹ãŠã®ããããã£ãå埩ããããšããŠããŸãã ç§ã®çŸåšã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãïŒååãé ãããŠããŸãïŒïŒ
type ContextKeyMap = Record<PropertyKey, ContextKeyValue>
function setFromObject(context: Context, object: ContextKeyMap) {
for (const key in object) {
if (hasOwn.call(object, key)) context.setKey(key, object[key])
}
for (const symbol of Object.getOwnPropertySymbols(object)) {
if (propertyIsEnumerable.call(object, symbol)) {
context.setKey(symbol, object[symbol as unknown as string])
}
}
}
ç§ã¯ãããå®è¡ã§ããããšã匷ãæãã§ããŸãïŒ
type ContextKeyMap = Record<PropertyKey, ContextKeyValue>
function setFromObject(context: Context, object: ContextKeyMap) {
for (const key in object) {
if (hasOwn.call(object, key)) context.setKey(key, object[key])
}
for (const symbol of Object.getOwnPropertySymbols(object)) {
if (propertyIsEnumerable.call(object, symbol)) {
context.setKey(symbol, object[symbol])
}
}
}
ã·ã³ãã«ã䜿çšããã€ã³ããã¯ã¹äœæã«ãåé¡ããããŸãã ç§ã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
const cacheProp = Symbol.for('[memoize]')
function ensureCache<T extends any>(target: T, reset = false): { [key in keyof T]?: Map<any, any> } {
if (reset || !target[cacheProp]) {
Object.defineProperty(target, cacheProp, {
value: Object.create(null),
configurable: true,
})
}
return target[cacheProp]
}
ç§ã¯@aaronpowellã«ãã解決ç
const cacheProp = Symbol.for('[memoize]') as any
function ensureCache<T extends Object & { [key: string]: any}>(target: T, reset = false): { [key in keyof T]?: Map<any, any> } {
if (reset || !target[cacheProp]) {
Object.defineProperty(target, cacheProp, {
value: Object.create(null),
configurable: true,
})
}
return target[cacheProp]
}
symbol
ããany
ãã£ã¹ãããã®ã¯ãããã»ã©è¯ãããšã§ã¯ãããŸããã
ä»ã®è§£æ±ºçã«ã¯æ¬åœã«æè¬ããŠããŸãã
@ahnpnlãã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãã·ã³ãã«ãããWeakMap
ã䜿çšããã»ããããã§ãããããšã³ãžã³ã¯ãããããé©åã«æé©åããŸããã€ãŸãã target
ã®ã¿ã€ããããã¯å€æŽãããŸããã ããã§ããã£ã¹ãããå¿
èŠããããããããŸãããããã£ã¹ãã¯æ»ãå€ã§çããŸãã
åé¿çã¯ããžã§ããªãã¯é¢æ°ã䜿çšããŠå€ãå²ãåœãŠãããšã§ã...
var theAnswer: symbol = Symbol('secret');
var obj = {} as Record<symbol, number>;
obj[theAnswer] = 42; // Currently error, but should be allowed
Object.assign(obj, {theAnswer: 42}) // allowed
åé¿çã¯ããžã§ããªãã¯é¢æ°ã䜿çšããŠå€ãå²ãåœãŠãããšã§ã...
var theAnswer: symbol = Symbol('secret'); var obj = {} as Record<symbol, number>; obj[theAnswer] = 42; // Currently error, but should be allowed Object.assign(obj, {theAnswer: 42}) // allowed
åæããŸããã ãããã®3ã€ã®ç·ã¯äºãã«çããã§ãïŒ
Object.assign(obj, {theAnswer: 42});
Object.assign(obj, {'theAnswer': 42});
obj['theAnswer'] = 42;
@DanielRosenwasser
ç§ã¯ãã®ãŠãŒã¹ã±ãŒã¹ãæã£ãŠããŸããéã³å Žã®ãªã³ã¯ã§ã¯ããããã䜿çšããŠåé¡ã解決ããŸããããèŠãç®ã¯éãã§ãã
const system = Symbol('system');
const SomeSytePlugin = Symbol('SomeSytePlugin')
/** I would prefer to have this working in TS */
interface Plugs {
[key: symbol]: (...args: any) => unknown;
}
const plugins = {
"user": {} as Plugs,
[system]: {} as Plugs
}
plugins[system][SomeSytePlugin] = () => console.log('awsome')
plugins[system][SomeSytePlugin](); ....
ããã§èšå·ã䜿çšãããšãæååã䜿çšãããšãã«çºçããå¯èœæ§ã®ããå¶çºçãªäžæžããé€å€ãããŸãã ããã«ãããã·ã¹ãã å šäœãããå ç¢ã«ãªããä¿å®ã容æã«ãªããŸãã
TSã§åäœããã³ãŒãã§åãå¯èªæ§ãæã€ä»£æ¿ãœãªã¥ãŒã·ã§ã³ãããå Žåã¯ãç§ã¯ãã¹ãŠã®è³ã§ãã
ãã®åé¡ã«ã€ããŠã®å ¬åŒã®èª¬æã¯ãããŸããïŒ
åé¿çã¯ããžã§ããªãã¯é¢æ°ã䜿çšããŠå€ãå²ãåœãŠãããšã§ã...
var theAnswer: symbol = Symbol('secret'); var obj = {} as Record<symbol, number>; obj[theAnswer] = 42; // Currently error, but should be allowed Object.assign(obj, {theAnswer: 42}) // allowed
ããªããæ¢ããŠããŸã
Objet.assign(obj, { [theAnswer]: 42 });
ãã ãããã£ã¹ãAFAIKãªãã§ä»¥äžã®ã³ã¡ã³ã2ãåç
§ããŠãã ãããx[theAnswer]
ãèªã¿æ»ãæ¹æ³ã¯ãããŸããã
ç¥ã®æã®ããã«ããããåªå ããŠãã ããã
ããªããæ¢ããŠããŸã
Objet.assign(obj, { [theAnswer]: 42 });
ãã ãããã£ã¹ãAFAIKãªãã§
x[theAnswer]
ãèªã¿æ»ãæ¹æ³ã¯ãããŸããã
mellonisãšMingweiSamuelãææããŠããããã«ããžã§ããªãã¯é¢æ°ã䜿çšããåé¿çã¯æ¬¡ã®ãšããã§ãã
var theAnswer: symbol = Symbol("secret");
var obj = {} as Record<symbol, number>;
obj[theAnswer] = 42; // Not allowed, but should be allowed
Object.assign(obj, { [theAnswer]: 42 }); // allowed
function get<T, K extends keyof T>(object: T, key: K): T[K] {
return object[key];
}
var value = obj[theAnswer]; // Not allowed, but should be allowed
var value = get(obj, theAnswer); // allowed
5幎ãšã€ã³ããã¯ã¹ãšããŠã®ã·ã³ãã«ã¯ãŸã èš±å¯ãããŠããŸãã
ãã®å Žåã®åé¿çãèŠã€ãããŸãããäžè¬çã§ã¯ãããŸããããå Žåã«ãã£ãŠã¯æ©èœããŸãã
const SYMKEY = Symbol.for('my-key');
interface MyObject { // Original object interface
key: string
}
interface MyObjectExtended extends MyObject {
[SYMKEY]?: string
}
const myObj: MyObject = {
'key': 'value'
}
// myObj[SYMKEY] = '???' // Not allowed
function getValue(obj: MyObjectExtended, key: keyof MyObjectExtended): any {
return obj[key];
}
function setValue(obj: MyObjectExtended, key: keyof MyObjectExtended, value: any): void {
obj[key] = value
}
setValue(myObj, SYMKEY, 'Hello world');
console.log(getValue(myObj, SYMKEY));
@ james4388ããªãã®äŸã¯
åèïŒ https ïŒ
ïŒèŠã€ããã°ããã§ããç§ã¯å®éã«ã¯TSããŒã ã®äžå¡ã§ã¯ãããŸãããïŒ
æãåèã«ãªãã³ã¡ã³ã
Typescript 3.0.1ãããã«åãŸããŸããã
symbol
ãåãå ¥ããã¬ã³ãŒãã欲ããã®ã§ãããTSã§ã¯èš±å¯ãããŸããããã®å·ãçºè¡ãããŠãã3ã5幎ã«ãªããŸãããä»ããã·ã³ãã«ãããã ããŸããð
ç®èãªããšã«ãTSã¯ããèªäœãšççŸããŠããŸãã
TSã¯
keyof any = number | string | symbol
ãŸããããããããªãã
record[symbol]
TSã¯èšãããšãæåŠããŸã_Type'symbol 'ã¯ã€ã³ãã¯ãµãŒãšããŠäœ¿çšã§ããŸãã_ã