TypeScript:描述对象的对象

时间:2018-12-11 22:29:01

标签: javascript typescript

说我有一个像这样的界面:

interface Student {
  firstName: string;
  lastName: string;
  year: number;
  id: number;
}

如果我想传递这些对象的数组,我可以简单地将类型写为Student[]

为了方便查找,我使用的是一个对象,其中学生ID是键,学生是值,而不是数组。

let student1: Student;
let student2: Student;
let students = {001: student1, 002: student2 }

是否可以将这种数据结构描述为我要传入函数或从函数返回的类型?

我可以这样定义一个接口:

interface StudentRecord {
  id: number;
  student: Student
}

但是那仍然不是我想要的类型。我需要表明我有一个对象满是对象,看起来像这样,Student[]表示我有一个满是这样的对象数组。

4 个答案:

答案 0 :(得分:3)

您可以简单地使密钥动态化:

interface IStudentRecord {
   [key: string]: Student
}

答案 1 :(得分:3)

使用内置的Record类型:

type StudentsById = Record<Student['id'], Student>;

答案 2 :(得分:0)

有几种解决方法:

字符串索引签名

@messerbill's answer所述,您可以为此使用索引签名:

interface StudentRecord {
    [P: string]: Student;
}

或者,如果您想更加谨慎:(请参阅下面的警告)

interface StudentRecordSafe {
    [P: string]: Student | undefined;
}

映射类型语法

或者,您也可以使用mapped type语法:

type StudentRecord = {
    [P in string]: Student;
}

或更谨慎的版本:(请参见下面的警告)

type StudentRecordSafe = {
    [P in String]?: Student
}

它与字符串索引签名非常相似,但是可以使用其他内容代替string,例如特定字符串的并集。还有一种实用程序类型,Record定义为:

type Record<K extends string, T> = {
    [P in K]: T;
}

,这意味着您也可以将其写为type StudentRecord = Record<string, Student>。 (或type StudentRecordSafe = Partial<Record<string, Student>>)(这是我通常的偏好,因为它是IMO,比长期使用的索引或类型映射语法更容易读写Record)

带有索引签名和映射类型语法的警告

这两者的一个警告是,他们对给定ID的学生的存在“持乐观态度”。他们假设,对于任何字符串键,都有一个对应的Student对象,即使不是这种情况:例如,这两个对象都可以编译:

const students: StudentRecord = {};
students["badId"].id // Runtime error: cannot read property id of undefind

使用相应的“谨慎”版本:

const students: StudentRecordSafe = {}
students["badId"].id;  // Compile error, object is potentially undefined

使用它有点烦人,特别是如果您知道只查找存在的ID,但绝对安全的话。

地图对象

稍作代码更改,但也可以使用适当的Map对象,并且它始终是“安全”版本,在该版本中您必须正确检查该内容`

type StudentMap = Map<string, Student>;
const students: StudentMap = new Map();
students.get("badId").id; // Compiler error, object might be undefined

答案 3 :(得分:-4)

让学生的状态= {001:student1,002:student2} 让students = {student1,student2},然后按他们的索引访问它们,例如students [0]和students [1],如果您需要学生信息,则可以像students [0] .firstName