我有一些JavaScript代码,使用对象作为字典;例如,“person”对象将保存一些个人详细信息,以电子邮件地址为键。

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

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

是否有可能在Typescript中描述这一点?或者我必须使用数组?


当前回答

你可以使用Record:

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

示例(一个AppointmentStatus enum和一些元数据之间的映射):

  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为值:

界面图标{ 名称:字符串 颜色:字符串 }

用法:

const icon: SemanticIcon = iconMapping[预约。状态)

其他回答

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

安装Lodash:

npm install lodash @types/lodash --save

进口及使用:

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

除了使用类似Map的对象外,实际的Map对象已经存在一段时间了,它在编译到ES6的TypeScript中可用,或者在使用带有ES6类型定义的polyfill时可用:

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总是有键类型和值类型,而对象可能没有索引签名 添加/删除项(键值对)的功能针对该任务进行了优化,不像在Object上创建属性

此外,Map对象为常见任务提供了一个更强大和优雅的API,其中大多数任务都不能通过简单的对象获得,除非将helper函数组合在一起(尽管其中一些任务需要一个完整的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());

你也可以在typescript中使用Record类型:

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

你可以使用Record:

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

示例(一个AppointmentStatus enum和一些元数据之间的映射):

  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为值:

界面图标{ 名称:字符串 颜色:字符串 }

用法:

const icon: SemanticIcon = iconMapping[预约。状态)

你可以像这样使用模板化接口:

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

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