说我有:
type User = {
...
}
我想创建一个新的user但将其设置为空对象:
const user: User = {}; // This fails saying property XX is missing
const user: User = {} as any; // This works but I don't want to use any
我该怎么做呢?我不希望变量为null。
Answers:
这是评论中值得注意的两个事项。
您希望用户的类型为
User | {}或Partial<User>,或者需要重新定义User类型以允许使用空对象。现在,编译器正确地告诉您该用户不是用户。–jcalz我认为这不应该被认为是正确的答案,因为它创建了一个不一致的类型实例,从而破坏了TypeScript的整个目的。在此示例中,该属性
Username未定义,而类型注释表示该属性不能未定义。–Ian Liu Rodrigues
TypeScript的设计目标之一是“在正确性和生产率之间取得平衡”。如果这样做会有所帮助,请使用类型断言为类型化变量创建空对象。
type User = {
Username: string;
Email: string;
}
const user01 = {} as User;
const user02 = <User>{};
user01.Email = "foo@bar.com";
这是一个适合您的示例。
Username未定义,而类型注释表示该属性不能未定义。
确实取决于您要执行的操作。类型是打字稿中的文档,因此您想要显示有关在创建类型时应如何使用此内容的意图。
将所有属性设为可选
type User = {
attr0?: number
attr1?: string
}
type User = {
...
}
let u1: User = null;
但是,实际上,如果要点是在知道将要分配给它的对象之前声明User对象,则您可能希望不let u1:User进行任何分配就这样做。
确实,打字稿的前提是要确保您符合在类型上概述的思维模型,以避免犯错误。如果要一一添加东西到对象,这是TypeScript试图使您不要这样做的习惯。
您更可能希望创建一些局部变量,然后在准备成为完整用户时将其分配给包含User的变量。这样一来,您就永远不会剩下部分格式的用户。那些事情太过分了。
let attr1: number = ...
let attr2: string = ...
let user1: User = {
attr1: attr1,
attr2: attr2
}
请注意,使用const user = {} as UserType仅提供智能感知,但在运行时user为空对象,{}并且内部没有属性。这意味着user.Email将给予undefined而不是""
type UserType = {
Username: string;
Email: string;
}
因此,使用classwithconstructor可以实际创建具有默认属性的对象。
type UserType = {
Username: string;
Email: string;
};
class User implements UserType {
constructor() {
this.Username = "";
this.Email = "";
}
Username: string;
Email: string;
}
const myUser = new User();
console.log(myUser); // output: {Username: "", Email: ""}
console.log("val: "+myUser.Email); // output: ""
您也可以使用interface代替type
interface UserType {
Username: string;
Email: string;
};
...,其余代码保持不变。
实际上,您甚至可以跳过该constructor部分并按如下方式使用它:
class User implements UserType {
Username = ""; // will be added to new obj
Email: string; // will not be added
}
const myUser = new User();
console.log(myUser); // output: {Username: ""}
user的类型是User | {}或Partial<User>,或者需要重新定义User类型以允许使用空对象。目前,编译器正确地告诉您user不是User。