Đối tượng trống kiểu chỉ định cho một biến đã nhập


85

Giả sử tôi có:

type User = {
...
}

Tôi muốn tạo một mới usernhưng đặt nó là một đối tượng trống:

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

Làm thế nào để tôi làm điều này? Tôi không muốn biến null.


13
Hoặc bạn muốn userthuộc loại User | {}hoặc Partial<User>, hoặc bạn cần xác định lại Userloại để cho phép một đối tượng trống. Ngay bây giờ, trình biên dịch đang cho bạn biết chính xác rằng đó userkhông phải là a User.
jcalz

Câu trả lời:


174

Cảnh báo

Đây là hai cảnh báo xứng đáng từ các ý kiến.

Hoặc bạn muốn người dùng thuộc loại User | {}hoặc Partial<User>, hoặc bạn cần xác định lại Userloại để cho phép một đối tượng trống. Ngay bây giờ, trình biên dịch đang cho bạn biết một cách chính xác rằng người dùng không phải là Người dùng. -jcalz

Tôi không nghĩ rằng đây nên được coi là một câu trả lời thích hợp vì nó tạo ra một thể hiện không nhất quán của kiểu, phá hoại toàn bộ mục đích của TypeScript. Trong ví dụ này, thuộc tính Usernamekhông được xác định, trong khi chú thích kiểu nói rằng nó không thể được xác định. -Ian Liu Rodrigues

Câu trả lời

Một trong những mục tiêu thiết kế của TypeScript"đạt được sự cân bằng giữa tính đúng đắn và năng suất." Nếu bạn làm việc này hiệu quả, hãy sử dụng Type Assertions để tạo các đối tượng trống cho các biến đã nhập.

type User = {
    Username: string;
    Email: string;
}

const user01 = {} as User;
const user02 = <User>{};

user01.Email = "foo@bar.com";

Đây là một ví dụ làm việc cho bạn .

Đây là các xác nhận kiểu làm việc với gợi ý.


9
Cảm ơn bạn! Điều này giải quyết nó! Đây nên được đánh dấu là câu trả lời đúng ...
Kokodoko

3
Tôi không nghĩ rằng đây nên được coi là một câu trả lời thích hợp vì nó tạo ra một thể hiện không nhất quán của kiểu, phá hoại toàn bộ mục đích của TypeScript. Trong ví dụ này, thuộc tính Usernamekhông được xác định, trong khi chú thích kiểu nói rằng nó không thể được xác định.
Ian Liu Rodrigues

2
Điểm tốt @IanLiuRodrigues. Tôi đã thêm một số lưu ý cho câu trả lời.
Shaun Luttin

1
@IanLiuRodrigues Một trong những mục tiêu của TypeScript là cân bằng giữa tính đúng đắn với năng suất, vì vậy để nói rằng điều này làm suy yếu toàn bộ mục đích của TypeScript là hơi cực đoan. github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
Shaun Luttin

21

Thực sự phụ thuộc vào những gì bạn đang cố gắng làm. Các loại là tài liệu trong bảng chữ, vì vậy bạn muốn thể hiện ý định về cách thứ này sẽ được sử dụng khi bạn tạo loại.

Tùy chọn 1: Nếu Người dùng có thể có một số nhưng không phải tất cả các thuộc tính trong suốt thời gian tồn tại của họ

Đặt tất cả các thuộc tính là tùy chọn

type User = {
  attr0?: number
  attr1?: string
}

Tùy chọn 2: Nếu các biến chứa Người dùng có thể bắt đầu rỗng

type User = {
...
}
let u1: User = null;

Mặc dù, thực sự, ở đây nếu vấn đề là khai báo đối tượng Người dùng trước khi nó có thể biết được những gì sẽ được gán cho nó, bạn có thể muốn thực hiện let u1:Usermà không cần bất kỳ nhiệm vụ nào.

Tùy chọn 3: Những gì bạn có thể muốn

Thực sự, tiền đề của việc sắp chữ là đảm bảo rằng bạn đang tuân theo mô hình tinh thần mà bạn đã phác thảo trong các loại để tránh mắc lỗi. Nếu bạn muốn thêm từng thứ vào một đối tượng, đây là một thói quen mà TypeScript đang cố gắng khiến bạn không làm.

Nhiều khả năng, bạn muốn tạo một số biến cục bộ, sau đó gán cho biến chứa Người dùng khi biến đó sẵn sàng trở thành Người dùng toàn quyền. Bằng cách đó, bạn sẽ không bao giờ bị bỏ lại với Người dùng được hình thành một phần. Những thứ đó thật thô thiển.

let attr1: number = ...
let attr2: string = ...
let user1: User = {
  attr1: attr1,
  attr2: attr2
}

Không chắc liệu đây có phải là những gì anh ta đang làm hay không, nhưng có thể chúng ta đang nói về một đối số riêng biệt được gọi là UserAttributes hoặc thứ gì đó xử lý các tham số đến. Nó có thể không phải là một đối tượng người dùng có thể chấp nhận được và do đó nó có thể được xác định riêng biệt.
phát hành

Đây không phải là câu trả lời được chấp nhận. Hãy xem bài viết của Shaun Luttin bên dưới.
thargenediad

1

bạn có thể làm điều này như bên dưới trong bảng chữ

 const _params = {} as any;

 _params.name ='nazeh abel'

vì typecript không hoạt động như javascript nên chúng ta phải tạo kiểu như bất kỳ nếu không nó sẽ không cho phép bạn gán động thuộc tính cho một đối tượng


0

Nếu bạn khai báo một đối tượng trống theo nghĩa đen và sau đó gán giá trị sau đó, thì bạn có thể coi những giá trị đó là tùy chọn (có thể có hoặc không), vì vậy chỉ cần nhập chúng là tùy chọn với dấu chấm hỏi:

type User = {
    Username?: string;
    Email?: string;
}

0

Lưu ý rằng sử dụng const user = {} as UserTypechỉ cung cấp intellisense nhưng trong thời gian chạy userlà đối tượng rỗng {}và không có thuộc tính bên trong. điều đó có nghĩa là user.Emailsẽ cho undefinedthay vì""

type UserType = {
    Username: string;
    Email: string;
}

Vì vậy, hãy sử dụng classvới constructorđể thực sự tạo các đối tượng với các thuộc tính mặc định.

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: ""

Bạn cũng có thể sử dụng interfacethay thếtype

interface UserType {
  Username: string;
  Email: string;
};

... và phần còn lại của mã vẫn như cũ.


Trên thực tế, bạn thậm chí có thể bỏ qua constructorphần và sử dụng nó như thế này:

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: ""}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.