TypeScript对象作为C#中的字典类型

时间:2012-11-29 17:41:45

标签: arrays object dictionary typescript

我有一些使用对象作为词典的JavaScript代码;例如,'person'对象将保留一些键入电子邮件地址的个人详细信息。

var people = {<email> : <'some personal data'>};

adding   > "people[<email>] = <data>;" 
getting  > "var data = people[<email>];" 
deleting > "delete people[<email>];"

有可能在Typescript中描述这个吗?或者我必须使用数组吗?

7 个答案:

答案 0 :(得分:474)

不确定

var map: { [email: string]: Customer; } = { };
map['foo@gmail.com'] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['bar@hotmail.com'] = 'x'; // Not OK, 'x' is not a customer

如果您不想每次都输入整个类型注释,也可以创建一个界面:

interface StringToCustomerMap {
    [email: string]: Customer;
}

var map: StringToCustomerMap = { };
// Equivalent to first line of above

在较新版本的打字稿中,您可以使用Record<string, Customer>

答案 1 :(得分:97)

除了使用map- 之类的对象之外,现在还有一段实际的Map object,在编译为ES6时,或者在使用polyfill时可以在TypeScript中使用使用ES6 type-definitions

let people = new Map<string, Person>();

它支持与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");

与使用map- 之类的对象相比,这一点有很多优点,例如:

  • 支持非基于字符串的密钥,例如数字或对象,Object都不支持这些数字或对象(不,Object不支持数字,它将它们转换为字符串)
  • 不使用--noImplicitAny时错误的空间较小,因为Map始终具有类型和类型,而对象可能没有索引签名
  • 添加/删除项目(键值对)的功能针对任务进行了优化,unlike creating properties on an Object

此外,Map对象为常见任务提供了更强大,更优雅的API,其中大部分都不能通过简单的Object获得,而不会将帮助函数混合在一起(尽管其中一些需要完整的用于ES5目标或以下的ES6迭代器/可迭代polyfill):

// 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());

答案 2 :(得分:73)

您可以使用如下模板化界面:

interface Map<T> {
    [K: string]: T;
}

let dict: Map<number> = {};
dict["one"] = 1;

答案 3 :(得分:5)

Lodash有一个简单的Dictionary实现,并且具有良好的TypeScript支持

安装Lodash:

npm install lodash @types/lodash --save

导入和使用:

import { Dictionary } from "lodash";
let properties : Dictionary<string> = {
    "key": "value"        
}
console.log(properties["key"])

答案 4 :(得分:5)

您还可以在打字稿中使用记录类型:

export interface nameInterface { 
    propName : Record<string, otherComplexInterface> 
}

答案 5 :(得分:2)

您可以使用Record

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

示例(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' }
  }

现在将接口作为值:

interface Icon { Name: string Color: string }

用法:

const icon: SemanticIcon = iconMapping[appointment.Status]

答案 6 :(得分:-1)

有一个库,可以在打字稿中提供强类型的可查询集合

集合是:

  • 列表
  • 字典

该库称为 ts-generic-collections 。 (Source code on GitHub

您可以创建字典并按以下方式查询它:

  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);
  });