2015-12-30 26 views
6

Đây là một ví dụ đơn giản hơn những gì tôi đang cố gắng để làm:Cách đúng để truyền một đối tượng JSON vào một biến kiểu đánh máy bằng cách sử dụng một lớp?

export class Person{ 
    id:Number; 
    name:String; 
} 

export class PersonForm{ 

    // This line: 
    default:Person = {name: "Guy"}; 
    // Gives the following error: 
    // Error:(25, 5) TS2322: Type '{ name: string; }' is not assignable to type 'Person'. 
    // Property 'id' is missing in type '{ name: string; }'. 

    // I tried <Person>{name: "Guy"} but it gives the same error. 

} 

Làm thế nào tôi có thể làm cho trình biên dịch bỏ qua vấn đề này càng lâu càng Im không sử dụng bất động sản không còn tồn tại, hoặc làm thế nào để khai báo lớp vì vậy tôi có thể thực hiện nhiệm vụ theo cách này thay vì Person mới() và sau đó chỉ thiết lập các thuộc tính mà tôi muốn.

Lưu ý: Gửi một đối tượng có tất cả các thuộc tính vào hàm tạo không phải là giải pháp mà tôi mong đợi. Cũng sử dụng một giao diện hoạt động vì tôi có thể khai báo các trường tùy chọn, làm thế nào tôi có thể làm tương tự trong một lớp?

Thêm một số thông tin thêm:

Mục đích chính của những gì tôi đang cố gắng để đạt được:

Tìm cách tốt nhất để khai báo một lớp (không phải là một giao diện) vì vậy tôi có thể khởi tạo nó với mã sạch trong một dòng thiết lập chỉ các tham số tôi muốn thiết lập. Trong Java, bạn sẽ quá tải các nhà xây dựng hoặc sử dụng mẫu Builder.

Tôi chắc chắn có thể thử mẫu trình xây dựng nhưng tôi đang tìm cách tạo kiểu chữ hơn để làm điều đó, nếu có.

+1

có gì sai với việc sử dụng một giao diện trong kịch bản này? Có vẻ như phù hợp nhất. – toskv

+1

Tôi nghĩ rằng các tùy chọn của bạn là tạo một giao diện w/thuộc tính tùy chọn và yêu cầu lớp của bạn triển khai giao diện hoặc chấp nhận giao diện làm tham số hàm tạo. Tại thời điểm này, không có cách nào để làm những gì bạn muốn, nhưng [những người khác đã yêu cầu] (https://github.com/Microsoft/TypeScript/issues/4889) cho nó. –

+0

cách khác bạn chỉ có thể tạo một hàm tạo cho lớp và gọi nó bằng tham số null .. giao diện sẽ vẫn tốt hơn cho trường hợp này. – toskv

Trả lời

3

tôi thấy cách dễ nhất để làm điều đó, và nó có thể. Tôi nghĩ rằng tôi đã thử nó theo cách này trước đây nhưng thực tế là tôi đã sử dụng "Number" & "String" loại thay vì "số" & "chuỗi", có thể cho tôi lỗi sai sót từ trình biên dịch, mã sau hoạt động kỳ diệu cho tôi:

export class Person{ 
    constructor(
     public id?: number, // make sure you use number and string types instead of Number and String types 
     public name?: string // make sure you make all properties optional using "?" 
    ){} 
} 

export class PersonForm{ 
    default:Person = <Person>{name: "Guy"}; 
} 
+0

' {name:" Guy "} instanceof Person; // false' –

+0

@JohnWhite yea, loại {name: "Guy"} là Object, nếu bạn muốn một cá thể của Person bạn cần gọi hàm tạo: 'new Person()' – Langley

0

Bạn có thể viết lớp của mình bằng một hàm tạo.

export class Person { 
    constructor(public id: number, public name: string) {} 
} 

Nhưng bạn sẽ phải gọi nó như thế này.

let person = new Person(null, "George"); 
+0

Bạn đang thiết lập tất cả các tham số ở đó, tôi muốn có khả năng chỉ thiết lập các thông số tôi muốn. Các giải pháp gần nhất tôi có là sử dụng constructors mặc dù, vì vậy bạn có thể đi đúng hướng. – Langley

+1

Thật vậy, bạn có thể sử dụng một nhà máy để tạo ra các mặt hàng, nhưng như tôi đã nói, {name: "Guy"} hoạt động tốt cho tôi. Bạn đang sử dụng phiên bản loại bản ghi nào? – toskv

+0

Hey toskv Tôi đã không nhìn thấy bình luận này, có vẻ như việc đúc là tốt, nó chỉ là cách để tuyên bố lớp sai để đạt được những gì tôi muốn, bạn đã đi đúng hướng nhưng trong ví dụ của bạn khởi tạo tất cả các thuộc tính, thay đổi nó để nó trông giống như cái tôi đã đăng và tôi sẽ thay đổi câu trả lời được chấp nhận cho bạn. – Langley

0

Truyền biểu thức JSON sang any. Dòng gán default trở thành:

default: Person = <any>{ name: "Guy" }; 
0

Đây là một lựa chọn để bổ sung cho các câu trả lời khác được đăng ở đây ..

Nếu bạn có một số đối tượng initialiser

{ 
    name:"John" 
} 

và bạn muốn một cách rõ ràng một ví dụ của lớp Person, nhưng muốn giữ đối tượng khởi tạo, trong khi vẫn giữ các giá trị mặc định mà lớp Person tạo, bạn có thể làm điều đó thông qua truyền toàn bộ đối tượng vào hàm tạo lớp:

var instance = new Person({name:"John"}); 

nơi

export class Person 
{ 
    id:number = 0; //or generate one 
    name:string = "unknown"; 
    constructor(opts:{id?:number; name?:string}){ 
     if(opts){ 
      this.id = opts.id || this.id; 
      this.name = opts.name || this.name; 
     } 
    } 
} 

ví dụ:

var people = [ 
    new Person(), 
    new Person({name:"John"}), 
    new Person({name:"James", id:10}), 
    new Person({id:20})]; 
Các vấn đề liên quan