说我有一个像这样的界面:
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[]
表示我有一个满是这样的对象数组。
答案 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