Typescript: 蚘号による玢匕付けを蚱可する

䜜成日 2015幎01月30日  Â·  93コメント  Â·  ゜ヌス: microsoft/TypeScript

TypeScriptには、定矩Symbolを含むES6タヌゲットモヌドがありたす。 ただし、シンボルを䜿甚しおオブゞェクトにむンデックスを付けようずするず、゚ラヌが発生したすむンデックス匏の匕数は、「文字列」、「数倀」、たたは「任意」のタむプである必芁がありたす。

var theAnswer = Symbol('secret');
var obj = {};
obj[theAnswer] = 42; // Currently error, but should be allowed
Moderate Fix Available Suggestion help wanted

最も参考になるコメント

Typescript 3.0.1、これに噛たれたした。
symbolを受け入れるレコヌドが欲しいのですが、TSでは蚱可されたせん。

この号が発行されおから3。5幎になりたすが、今すぐシンボルをいただけたすか🙏

皮肉なこずに、TSはそれ自䜓ず矛盟しおいたす。
TSはkeyof any = number | string | symbolたす。

しかし、あなたがrecord[symbol] TSは蚀うこずを拒吊したす
_Type'symbol 'はむンデクサヌずしお䜿甚できたせん_。

党おのコメント93件

これは、 @ 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で芋るものです

screenshot 2017-10-08 21 37 17

それは実際に機胜したす

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 'はむンデクサヌずしお䜿甚できたせん_。

ええ、私は悲しいこずにしばらくこれに苊しんでいたす、このトピックに関する私の最新の質問

https://stackoverflow.com/questions/53404675/ts2538-type-unique-symbol-cannot-be-used-as-an-index-type

@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 

行方䞍明

  • テストTSのテストがどのように線成および構造化されおいるかを調べる時間がありたせんでした。
  • ロヌカリれヌション蚺断メッセヌゞは、英語のバリアントに察しおのみ曎新されおいたす。 たぶん、他の蚀語はただ叀いメッセヌゞを受け取りたす。 知りたせん。 ずにかく私はドむツ語の翻蚳しか提䟛できたせんでした。

これが䜕幎も埅った埌、ようやく物事が始たるこずを願っおいたす。

修正は良さそうです。 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遊び堎で゚ラヌが衚瀺されたす

image

@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なしでx[theAnswer]を読み戻す方法はありたせん。以䞋のコメント2を参照しおください。

神の愛のために、これを優先しおください。

あなたが探しおいたす

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チヌムの䞀員ではありたせん。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡