Kiểm tra loại lớp trong TypeScript


240

Trong ActionScript, có thể kiểm tra loại tại thời gian chạy bằng toán tử is :

var mySprite:Sprite = new Sprite(); 
trace(mySprite is Sprite); // true 
trace(mySprite is DisplayObject);// true 
trace(mySprite is IEventDispatcher); // true

Có thể phát hiện nếu một biến (mở rộng hoặc) là một lớp hoặc giao diện nhất định với TypeScript không?

Tôi không thể tìm thấy bất cứ điều gì về nó trong thông số kỹ thuật ngôn ngữ. Nó nên ở đó khi làm việc với các lớp / giao diện.

Câu trả lời:


318

4.19.4 Toán tử instanceof

Các instanceofnhà điều hành đòi hỏi các toán hạng bên trái là loại Bất kỳ, một loại đối tượng, hoặc một loại tham số kiểu, và các toán hạng phải là loại Bất kỳ hoặc một subtype của 'Chức năng' kiểu giao diện. Kết quả luôn thuộc kiểu nguyên thủy Boolean.

Vì vậy, bạn có thể sử dụng

mySprite instanceof Sprite;

Lưu ý rằng toán tử này cũng có trong ActionScript nhưng nó không nên được sử dụng ở đó nữa:

Toán tử is, mới cho ActionScript 3.0, cho phép bạn kiểm tra xem một biến hoặc biểu thức có phải là thành viên của một loại dữ liệu nhất định hay không. Trong các phiên bản trước của ActionScript, toán tử instanceof đã cung cấp chức năng này, nhưng trong ActionScript 3.0, toán tử instanceof không nên được sử dụng để kiểm tra tư cách thành viên loại dữ liệu. Toán tử is nên được sử dụng thay cho toán tử instanceof để kiểm tra kiểu thủ công, bởi vì biểu thức x instanceof y chỉ kiểm tra chuỗi nguyên mẫu của x để biết sự tồn tại của y (và trong ActionScript 3.0, chuỗi nguyên mẫu không cung cấp một bức tranh hoàn chỉnh về hệ thống phân cấp thừa kế).

TypeScript có instanceofchung vấn đề. Vì nó là ngôn ngữ vẫn đang được phát triển nên tôi khuyên bạn nên nêu một đề xuất của cơ sở đó.

Xem thêm:


54

TypeScript có cách xác nhận loại biến trong thời gian chạy. Bạn có thể thêm một hàm xác nhận trả về một biến vị ngữ . Vì vậy, bạn có thể gọi hàm này bên trong một câu lệnh if và chắc chắn rằng tất cả các mã bên trong khối đó đều an toàn để sử dụng như kiểu bạn nghĩ.

Ví dụ từ các tài liệu TypeScript:

function isFish(pet: Fish | Bird): pet is Fish {
   return (<Fish>pet).swim !== undefined;
}

// Both calls to 'swim' and 'fly' are now okay.
if (isFish(pet)) {
  pet.swim();
}
else {
  pet.fly();
}

Xem thêm tại: https://www.typescriptlang.org/docs/handbook/advified-types.html


29
Đây không phải là lỗi đánh máy thời gian chạy, nó chỉ kiểm tra xem một đối tượng có thuộc tính nhất định hay không. Điều này có thể tốt cho các loại kết hợp vì vậy hoạt động cho trường hợp cụ thể này, nhưng thực sự không thể thực hiện được để tạo ra một "isT Breathy" cho mọi thứ như thế này. Ngoài ra nếu cả cá và chim có thể bơi, bạn sẽ phải chịu số phận. Tôi rất vui vì tôi đang sử dụng Haxe có kiểm tra loại đáng tin cậy để bạn có thể thực hiện Std.is(pet, Fish), hoạt động trên các loại, giao diện, v.v.
Mark Knol

4
Tôi thấy câu trả lời này hữu ích, nhưng tôi nghĩ bạn có thể điều chỉnh nó chính xác hơn một chút. Bản isFishthân nó là vị ngữ được tạo ra và cơ thể của nó không phải là vị ngữ một lớp. Ưu điểm của việc này là trình biên dịch hiểu tại thời điểm biên dịch các hàm thích hợp có thể, nhưng mã bên trong của bạn isFishđược thực thi trong thời gian chạy. Bạn thậm chí có thể có bộ bảo vệ chứa một instanceofcâu lệnh, ví dụ return pet instanceof Fish(giả sử đó là một lớp chứ không phải giao diện), nhưng điều này sẽ không cần thiết vì trình biên dịch hiểu instanceoftrực tiếp.

4
đây cũng được gọi là "Bộ lọc
Julian

@MarkKnol nó thực sự là kiểm tra thời gian chạy nhưng cũng mang đến khả năng hiểu kiểu đánh máy (nghĩa là: bạn có thể tin tôi đây sẽ là loại X hoặc Y vì tôi sẽ kiểm tra nó khi chạy).
Flavien Volken

3
Bạn có thể muốn xem xét sử dụng (pet as Fish)vì tslinter sẽ phàn nàn về (<Fish>pet). Xem tài liệu tslint
Bryan

1

Bạn có thể sử dụng instanceoftoán tử cho việc này. Từ MDN:

Toán tử instanceof kiểm tra xem thuộc tính nguyên mẫu của hàm tạo có xuất hiện ở bất kỳ đâu trong chuỗi nguyên mẫu của một đối tượng hay không.

Nếu bạn không biết nguyên mẫu và chuỗi nguyên mẫu nào thì tôi khuyên bạn nên tìm kiếm nó. Ngoài ra đây là một ví dụ về JS (TS hoạt động tương tự về mặt này) có thể làm rõ khái niệm:

    class Animal {
        name;
    
        constructor(name) {
            this.name = name;
        }
    }
    
    const animal = new Animal('fluffy');
    
    // true because Animal in on the prototype chain of animal
    console.log(animal instanceof Animal); // true
    // Proof that Animal is on the prototype chain
    console.log(Object.getPrototypeOf(animal) === Animal.prototype); // true
    
    // true because Object in on the prototype chain of animal
    console.log(animal instanceof Object); 
    // Proof that Object is on the prototype chain
    console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
    
    console.log(animal instanceof Function); // false, Function not on prototype chain
    
    

Chuỗi nguyên mẫu trong ví dụ này là:

động vật> Animal.prototype> Object.prototype

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.