如何定义对象数组?

我在TypeScript中创建了一个对象数组:

 userTestStatus xxxx = {
"0": { "id": 0, "name": "Available" },
"1": { "id": 1, "name": "Ready" },
"2": { "id": 2, "name": "Started" }
};

有人能告诉我如何正确地声明它的类型吗?它是可能做内联或我需要两个定义?

我想用一个类型声明替换xxx,这样以后如果我错误地使用了userTestStatus[3].nammme之类的东西,TypeScript就会提醒我。

876982 次浏览

您真正想要的可能只是一个枚举

如果您正在寻找一些行为类似于枚举的东西(因为我看到您正在定义一个对象并附加一个顺序ID 0,1,2,并且包含一个您不想拼错的名称字段(例如name vs naaame),那么您最好定义一个枚举,因为顺序ID会自动处理,并为您提供开箱即用的类型验证。

enum TestStatus {
Available,     // 0
Ready,         // 1
Started,       // 2
}


class Test {
status: TestStatus
}


var test = new Test();
test.status = TestStatus.Available; // type and spelling is checked for you,
// and the sequence ID is automatic

上面的值将被自动映射,例如。"0"代表"Available",你可以使用TestStatus.Available访问它们。当你传递这些时Typescript会强制执行类型。

如果坚持将新类型定义为自定义类型的数组

你想要一个对象的数组,(不是一个键为"0","1"和"2"的对象),所以让我们先定义对象的类型,然后定义一个包含数组的类型。

class TestStatus {
id: number
name: string


constructor(id, name){
this.id = id;
this.name = name;
}
}


type Statuses = Array<TestStatus>;


var statuses: Statuses = [
new TestStatus(0, "Available"),
new TestStatus(1, "Ready"),
new TestStatus(2, "Started")
]

上面的是一个对象,不是数组。

要创建数组,请使用[ &]来包围你的对象。

userTestStatus = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];

除此之外,TypeScript是JavaScript的超集,所以任何有效的JavaScript都将是有效的TypeScript,因此不需要其他更改。

来自OP的反馈澄清…需要一个模型的定义张贴

你可以使用这里定义的类型来表示你的对象模型:

type MyType = {
id: number;
name: string;
}


type MyGroupType = {
[key:string]: MyType;
}


var obj: MyGroupType = {
"0": { "id": 0, "name": "Available" },
"1": { "id": 1, "name": "Ready" },
"2": { "id": 2, "name": "Started" }
};
// or if you make it an array
var arr: MyType[] = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];

你最好使用本地数组而不是具有类似数字属性的对象文字,这样编号(以及许多其他数组函数)就可以得到现成的处理。

你在这里寻找的是数组的内联接口定义,它定义了数组中的每个元素,无论是最初出现的还是后来引入的:

let userTestStatus: { id: number, name: string }[] = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];


userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

如果你马上用值初始化你的数组,显式类型定义是不必要的;TypeScript可以从初始赋值自动推断出大多数元素类型:

let userTestStatus = [
{ "id": 0, "name": "Available" },
...
];


userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

一些tslint规则禁止使用[],例如消息:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

然后你可以这样写:

var userTestStatus: Array<{ id: number, name: string }> = Array(
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
);

你也可以试试

    interface IData{
id: number;
name:string;
}


let userTestStatus:Record<string,IData> = {
"0": { "id": 0, "name": "Available" },
"1": { "id": 1, "name": "Ready" },
"2": { "id": 2, "name": "Started" }
};

检查record如何工作:https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

在我们的例子中,Record用于声明一个对象,该对象的键为字符串,值为IData类型,因此现在当我们尝试访问其属性时,它将为我们提供智能感知,并在我们尝试userTestStatus[0].nameee这样的属性时抛出类型错误

 var xxxx : { [key:number]: MyType };

Array<T>

person: Array<{
name: string;
age: number;
}>

有点老了,但我觉得我可以解释清楚。

确切的答案

    interface MyObject {
id: number;
name: string;
}


interface MyExactData {
[key: string]: MyObject;
}


let userTestStatus: MyExactData = {
"0": { "id": 0, "name": "Available" },
"1": { "id": 1, "name": "Ready" },
"2": { "id": 2, "name": "Started" }
};


但上面不是我们通常处理对象数组的方式,你会在javaScript中使用简单的本机数组。

    interface MyObject { // define the object (singular)
id: number;
name: string;
}


let userTestStatus_better: MyObject[] = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];


简单地将[]添加到我们的接口中,就提供了上述对象数组的类型。 inline

    let userTestStatus_inline: {id:number, name:string}[] = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];

我将使用接口,因为您有一些可定义、可理解和可重用的东西。如果您需要进行更改,您可以更改一个接口,typescript将报告您的接口代码不匹配。