回答:
var stuff: { [key: string]: string; } = {};
stuff['a'] = ''; // ok
stuff['a'] = 4; // error
// ... or, if you're using this a lot and don't want to type so much ...
interface StringMap { [key: string]: string; }
var stuff2: StringMap = { };
// same as above
number
インデックスタイプとしても使用可能
type Keys = 'Acceptable' | 'String' | 'Keys'
をインデックス(キー)タイプとして使用することは可能ですか(または可能ですか)?
interface AgeMap {
[name: string]: number
}
const friendsAges: AgeMap = {
"Sandy": 34,
"Joe": 28,
"Sarah": 30,
"Michelle": "fifty", // ERROR! Type 'string' is not assignable to type 'number'.
};
ここで、インターフェイスはAgeMap
キーを文字列として、値を数値として適用します。キーワードname
は任意の識別子にすることができ、インターフェイス/タイプの構文を提案するために使用する必要があります。
同様の構文を使用して、オブジェクトが共用体タイプのすべてのエントリのキーを持つように強制できます。
type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
type ChoresMap = { [day in DayOfTheWeek]: string };
const chores: ChoresMap = { // ERROR! Property 'saturday' is missing in type '...'
"sunday": "do the dishes",
"monday": "walk the dog",
"tuesday": "water the plants",
"wednesday": "take out the trash",
"thursday": "clean your room",
"friday": "mow the lawn",
};
もちろん、これをジェネリック型にすることもできます!
type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
type DayOfTheWeekMap<T> = { [day in DayOfTheWeek]: T };
const chores: DayOfTheWeekMap<string> = {
"sunday": "do the dishes",
"monday": "walk the dog",
"tuesday": "water the plants",
"wednesday": "take out the trash",
"thursday": "clean your room",
"friday": "mow the lawn",
"saturday": "relax",
};
const workDays: DayOfTheWeekMap<boolean> = {
"sunday": false,
"monday": true,
"tuesday": true,
"wednesday": true,
"thursday": true,
"friday": true,
"saturday": false,
};
10.10.2018の更新:以下の@dracstaxiの回答を確認してください-これのRecord
ほとんどを行う組み込み型があります。
1.2.2020の更新: 作成済みのマッピングインターフェイスを回答から完全に削除しました。@dracstaxiの答えは、それらを完全に無関係にします。引き続き使用する場合は、編集履歴を確認してください。
x = {}; x[1] = 2;
、Chromeで実行すると、Object.keys(x)
["1"] JSON.stringify(x)
が返され、 '{"1":2}'が返されます。typeof Number
(例:Infinity、NaN、1e300、999999999999999999999など)のコーナーケースは、文字列キーに変換されます。また、のような文字列キーの他のコーナーケースには注意してくださいx[''] = 'empty string';
、x['000'] = 'threezeros';
x[undefined] = 'foo'
。
簡単な更新:Typescript 2.1以降Record<T, K>
、辞書のように機能する組み込み型があります。
ドキュメントの例:
// For every properties K of type T, transform it to U
function mapObject<K extends string, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>
const names = { foo: "hello", bar: "world", baz: "bye" };
const lengths = mapObject(names, s => s.length); // { foo: number, bar: number, baz: number }
TypeScript 2.1ドキュメント Record<T, K>
これを使用する上{[key: T]: K}
で私が目にする唯一の欠点は、「キー」の代わりに使用しているキーの種類に関する有用な情報をエンコードできることです。たとえば、オブジェクトに素数キーしかない場合は、次のようにヒントを与えることができます{[prime: number]: yourType}
。
これらの変換を支援するために私が書いた正規表現は次のとおりです。これにより、ラベルが「キー」であるケースのみが変換されます。他のラベルを変換するには、最初のキャプチャグループを変更するだけです。
検索: \{\s*\[(key)\s*(+\s*:\s*(\w+)\s*\]\s*:\s*([^\}]+?)\s*;?\s*\}
交換: Record<$2, $3>
{}
ますか?
Record
s(たとえば、Javascript Map
s とは異なり)は、オブジェクトリテラルの内容を強制する方法を提供するだけです。あなたがすることはできませんnew Record...
とconst blah: Record<string, string>;
にコンパイルされますconst blah;
。
Record
sでも機能することを言及する価値がある: const isBroken: Record<"hat" | "teapot" | "cup", boolean> = { hat: false, cup: false, teapot: true };
@Ryan Cavanaughの回答はまったく問題なく、有効です。それでも、Fall'16の時点で、ES6が大多数のプラットフォームでサポートされていると主張できる場合は、データに何らかのキーを関連付ける必要がある場合は常にMapを使用する方がよいことを付け加えておきます。
書くときはlet a: { [s: string]: string; }
、typescriptがコンパイルされた後、型データのようなものはなく、それはコンパイルにのみ使用されることを覚えておく必要があります。そして{[s:string]:string; }は単に{}にコンパイルされます。
そうは言っても、次のようなものを書いたとしても:
class TrickyKey {}
let dict: {[key:TrickyKey]: string} = {}
でも、これは単に(コンパイルされませんtarget es6
、あなたが買ってあげますerror TS1023: An index signature parameter type must be 'string' or 'number'.
したがって、実際には潜在的なキーとして文字列または数値に制限されているため、ここではタイプチェックを強制するという意味はそれほどありません。特に、jsが数値でキーにアクセスしようとすると、文字列に変換されることに注意してください。
したがって、キーが文字列であってもMapを使用するのがベストプラクティスであると想定するのは非常に安全であるため、次のようにします。
let staff: Map<string, string> = new Map();
let dict: {[key in TrickyKey]: string} = {}
- TrickyKey
は文字列リテラルタイプです(例:)"Foo" | "Bar"
。
Map
オブジェクトに固執する方がほとんど常に良いという考えには同意しません。マップには追加のメモリオーバーヘッドが伴うため、(さらに重要なことに)JSON文字列として保存されているデータから手動でインスタンス化する必要があります。それらはしばしば非常に便利ですが、純粋に型を取得するためではありません。