TypeScript 对象作为 C# 中的字典类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13631557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript Objects as Dictionary types as in C#
提问by Robert Taylor
I have some JavaScript code that uses objects as dictionaries; for example a 'person' object will hold a some personal details keyed off the email address.
我有一些使用对象作为字典的 JavaScript 代码;例如,“人”对象将保留一些从电子邮件地址中删除的个人详细信息。
var people = {<email> : <'some personal data'>};
adding > "people[<email>] = <data>;"
getting > "var data = people[<email>];"
deleting > "delete people[<email>];"
Is it possible to describe this in Typescript? or do I have to use an Array?
是否可以在 Typescript 中对此进行描述?还是我必须使用数组?
回答by Ryan Cavanaugh
In newer versions of typescript you can use:
在较新版本的打字稿中,您可以使用:
type Customers = Record<string, Customer>
In older versions you can use:
在旧版本中,您可以使用:
var map: { [email: string]: Customer; } = { };
map['[email protected]'] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['[email protected]'] = 'x'; // Not OK, 'x' is not a customer
You can also make an interface if you don't want to type that whole type annotation out every time:
如果您不想每次都输入整个类型注释,您也可以创建一个接口:
interface StringToCustomerMap {
[email: string]: Customer;
}
var map: StringToCustomerMap = { };
// Equivalent to first line of above
回答by John Weisz
In addition to using an map-likeobject, there has been an actual Map
objectfor some time now, which is available in TypeScript when compiling to ES6, or when using a polyfill with the ES6 type-definitions:
除了使用类似地图的对象之外,一段时间以来一直有一个实际的Map
对象,它在编译为 ES6 时在 TypeScript 中可用,或者在使用带有 ES6类型定义的polyfill 时可用:
let people = new Map<string, Person>();
It supports the same functionality as Object
, and more, with a slightly different syntax:
它支持与 相同的功能Object
,但语法略有不同:
// Adding an item (a key-value pair):
people.set("John", { firstName: "John", lastName: "Doe" });
// Checking for the presence of a key:
people.has("John"); // true
// Retrieving a value by a key:
people.get("John").lastName; // "Doe"
// Deleting an item by a key:
people.delete("John");
This alone has several advantages over using a map-likeobject, such as:
与使用类似地图的对象相比,仅此一项就有几个优点,例如:
- Support for non-string based keys, e.g. numbers or objects, neither of which are supported by
Object
(no,Object
does not support numbers, it converts them to strings) - Less room for errors when not using
--noImplicitAny
, as aMap
always has a keytype and a valuetype, whereas an object mightnot have an index-signature - The functionality of adding/removing items (key-value pairs) is optimized for the task, unlike creating properties on an
Object
- 支持非基于字符串的键,例如数字或对象,两者都不支持
Object
(不,Object
不支持数字,它将它们转换为字符串) - 不使用时出错的余地较小
--noImplicitAny
,因为 aMap
始终具有键类型和值类型,而对象可能没有索引签名 - 添加/删除项目(键值对)的功能针对任务进行了优化,不像在
Object
Additionally, a Map
object provides a more powerful and elegant API for common tasks, most of which are not available through simple Object
s without hacking together helper functions (although some of these require a full ES6 iterator/iterable polyfill for ES5 targets or below):
此外,Map
对象为常见任务提供了更强大、更优雅的 API,其中大部分都不能通过简单的Object
s 获得,除非将辅助函数组合在一起(尽管其中一些需要完整的 ES6 迭代器/可迭代的 polyfill,用于 ES5 目标或更低版本):
// Iterate over Map entries:
people.forEach((person, key) => ...);
// Clear the Map:
people.clear();
// Get Map size:
people.size;
// Extract keys into array (in insertion order):
let keys = Array.from(people.keys());
// Extract values into array (in insertion order):
let values = Array.from(people.values());
回答by Dimitar Mazhlekov
You can use templated interfaces like this:
您可以使用这样的模板化接口:
interface Map<T> {
[K: string]: T;
}
let dict: Map<number> = {};
dict["one"] = 1;
回答by Twen
You can also use the Record type in typescript :
您还可以在打字稿中使用 Record 类型:
export interface nameInterface {
propName : Record<string, otherComplexInterface>
}
回答by phil
Lodash has a simple Dictionary implementation and has good TypeScript support
Lodash 有一个简单的 Dictionary 实现并且有很好的 TypeScript 支持
Install Lodash:
安装 Lodash:
npm install lodash @types/lodash --save
Import and usage:
导入和使用:
import { Dictionary } from "lodash";
let properties : Dictionary<string> = {
"key": "value"
}
console.log(properties["key"])
回答by Nick N.
You can use Record
for this:
您可以Record
为此使用:
https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt
https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt
Example (A mapping between AppointmentStatus enum and some meta data):
示例(AppointmentStatus 枚举和一些元数据之间的映射):
const iconMapping: Record<AppointmentStatus, Icon> = {
[AppointmentStatus.Failed]: { Name: 'calendar times', Color: 'red' },
[AppointmentStatus.Canceled]: { Name: 'calendar times outline', Color: 'red' },
[AppointmentStatus.Confirmed]: { Name: 'calendar check outline', Color: 'green' },
[AppointmentStatus.Requested]: { Name: 'calendar alternate outline', Color: 'orange' },
[AppointmentStatus.None]: { Name: 'calendar outline', Color: 'blue' }
}
Now with interface as value:
现在以接口作为值:
interface Icon {
Name: string
Color: string
}
interface Icon {
Name: string
Color: string
}
Usage:
用法:
const icon: SemanticIcon = iconMapping[appointment.Status]
const icon: SemanticIcon = iconMapping[appointment.Status]
回答by John
There is a library which provides strongly-typed, queryable collectionsin typescript.
有一个库在打字稿中提供强类型、可查询的集合。
The collections are:
集合是:
- List
- Dictionary
- 列表
- 字典
The library is called ts-generic-collections. (Source code on GitHub)
该库名为ts-generic-collections。(GitHub 上的源代码)
You can create a dictionary and query it like below:
您可以创建一个字典并像下面这样查询它:
it('firstOrDefault', () => {
let dictionary = new Dictionary<Car, IList<Feature>>();
let car = new Car(1, "Mercedez", "S 400", Country.Germany);
let car2 = new Car(2, "Mercedez", "S 500", Country.Germany);
let features = new List<Feature>();
let feature = new Feature(1, "2 - Door Sedan");
features.add(feature);
dictionary.add(car, features);
features = new List<Feature>();
feature = new Feature(2, "4 - Door Sedan");
features.add(feature);
dictionary.add(car2, features);
//query
let first = dictionary.firstOrDefault(x => x.key.name == "Mercedez");
expect(first.key.id = 1);
});