2017-06-20 19 views
8

Tôi sử dụng phiên bản TypeScript 2.3.4. Tôi muốn viết một hàm chấp nhận một đối tượng phải có các trường được chỉ định. Nhưng đối tượng này không nên chứa bất kỳ trường nào khác. Làm thế nào tôi có thể đạt được điều này?Lớp/giao diện nghiêm ngặt của TypeScript

Hiện tại, tính năng này chỉ hoạt động nếu tôi xác định nội tuyến đối tượng. Nhưng nếu tôi sử dụng một đối tượng khác với các trường thừa - trình biên dịch sẽ cho phép nó. Điều gì là hoàn toàn sai.

Ví dụ:

function foo(arg: { a: string }) { // there is tons of fields actually 
    // ... 
} 

foo ({a: "qwerty"}); // No Error - ok 

foo ({a: "qwerty", b: 123}); // Error - ok 

let bar = { 
    a: "qwerty", 
    b: 123 
}; 

foo (bar); // No Error - NOT OK !!! 

Mã tương tự có thể được lớn không lành mạnh với giao diện, các lớp học, tờ khai loại - đó là cùng một vấn đề.

Bây giờ tôi phải trích xuất các trường từ đối tượng theo cách thủ công để đảm bảo rằng không có trường bổ sung nào. Nhưng tôi không thể phát tán giải pháp này trên ~ 1000 chức năng (tôi thực sự cần điều này) trên tất cả các mã - nó quá lộn xộn. Tôi tạo trình bao bọc API và tôi cần đảm bảo rằng không có trường bổ sung hoặc sai nào được truyền cho máy chủ.

+0

Có vẻ như đó là cố ý. Xem [vấn đề này] (https://github.com/Microsoft/TypeScript/issues/13444) và [this] (https://github.com/Microsoft/TypeScript/issues/3755) để thảo luận thêm. – Saravana

+0

Saravana, vâng, tôi đọc điều này, nhưng không có câu trả lời cho câu hỏi của tôi trong các cuộc thảo luận. Tôi nghĩ sẽ tốt hơn nếu bạn tránh sự khắt khe của các giao diện, nhưng hãy để nó cho các lớp học. –

Trả lời

2

Các tính năng mà bạn đang yêu cầu được biết đến như "exact types".
Nó đang được xem xét, đó là, không bị từ chối cũng như không được chấp nhận, và các cuộc thảo luận vẫn tiếp tục.

1

Đây là cách hoạt động của thiết kế và tôi không chắc chắn bạn có thể làm việc này xung quanh. See the docs để biết thêm thông tin.

Điều bạn cũng làm sai - bạn không thể chắc chắn 100% về những gì được gửi tới máy chủ. Miễn là trình duyệt không biết gì về TS, một số thư viện có thể đưa vào bất kỳ yêu cầu nào bất cứ điều gì cần thiết với ví dụ: bằng cách ghi đè các phương thức XmlHttpRequest (đây là ví dụ, ví dụ: ít nhất zone.js của angular).

Một cách khác để dễ dàng phá vỡ ý định của bạn cũng đơn giản như sử dụng <any> trước bất kỳ thông số nào bạn vượt qua.

TypeScript nhằm cải thiện quy trình phát triển của bạn nhưng tôi không nghĩ rằng nó có thể được sử dụng cho các nhu cầu như của bạn. Điều này thường được bảo hiểm bằng cách viết các bài kiểm tra thích hợp.

+0

Tất nhiên tôi biết rằng TS đã biên dịch sang JS, nơi không có lớp hoặc kiểm tra loại nào! Tôi cần phải bảo đảm phương pháp của mình từ các nhà phát triển khác trong quá trình phát triển. Điều này tất cả về phát triển.Ví dụ trường hợp thực tế: https://codepen.io/HarryBurns/pen/LLWoVa.typescript –

1

Có "là" một cách, nhưng bạn phải tự mình thực hiện. Nó được gọi là "User Defined Loại Guard" và nó trông như thế này:

interface Test { 
    prop: number; 
} 

function isTest(arg: any): arg is Test { 
    return arg && arg.prop && typeof(arg.prop) == 'number'; 
} 
+0

Tốt hơn nên làm với Reflection (xem http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from -novice-to-expert-part-4), vì vậy nó sẽ ngắn hơn, giống như 'kiểm tra (myObject)'. Hoặc, trong trường hợp của tôi là 'chọn (myObject)'. Hoạt động như hàm underscore/lodash 'pick'. –

2

Necromancing.
Nó đến với nguyên cảo 2.4:

type foo = { 
    a:string; 
    b:number; 
    opt?:string; 
} 


function test(obj:foo) 
{} 

test({ a:"", b:123, e:"produceError"}); 

Và để thực thi nó là một đối tượng, nếu tất cả các thông số là tùy chọn:

function test(obj:foo & object) 
{} 

Và nếu bạn muốn vượt qua hoặc là một chuỗi hoặc một đối tượng kiểu khác :

function test(obj: string | foo & object) 
{} 
Các vấn đề liên quan