Từ khóa `is` làm gì trong bảng chữ?


109

Tôi đã xem qua một số mã trông giống như sau:

export function foo(arg: string): arg is MyType {
    return ...
}

Tôi không thể tìm kiếm istrong tài liệu hoặc google, đó là một từ khá phổ biến và hiển thị trên mọi trang về cơ bản.

Từ khóa làm gì trong bối cảnh đó?

Câu trả lời:


115
function isString(test: any): test is string{
    return typeof test === "string";
}

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length); // string function
    }
}
example("hello world");

Sử dụng vị từ kiểu "test is string" ở định dạng trên (thay vì chỉ sử dụng boolean cho kiểu trả về, sau khi isString () được gọi, nếu hàm trả về true, TypeScript sẽ thu hẹp kiểu thành chuỗi trong bất kỳ khối nào được bảo vệ bởi a gọi hàm. Trình biên dịch sẽ nghĩ rằng foo là chuỗi trong khối được bảo vệ bên dưới (và CHỈ trong khối được bảo vệ bên dưới)

{
    console.log("it is a string" + foo);
    console.log(foo.length); // string function
}

Vị từ loại chỉ được sử dụng trong thời gian biên dịch. Kết quả tệp .js (thời gian chạy) sẽ không có sự khác biệt vì nó không xem xét TYPE.

Tôi sẽ minh họa sự khác biệt trong bốn ví dụ dưới đây.

Vd 1: đoạn mã ví dụ trên sẽ không có lỗi biên dịch và lỗi thời gian chạy.

Ví dụ 2: mã ví dụ dưới đây sẽ có lỗi biên dịch (cũng như lỗi thời gian chạy) vì TypeScript đã thu hẹp kiểu thành chuỗi và kiểm tra rằng toExponential không thuộc phương thức chuỗi.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Ví dụ 3: mã ví dụ dưới đây không có lỗi biên dịch nhưng sẽ có lỗi thời gian chạy vì TypeScript sẽ CHỈ thu hẹp kiểu thành chuỗi trong khối được bảo vệ nhưng không theo sau, do đó foo.toExponential sẽ không tạo ra lỗi biên dịch (TypeScript không nghĩ là như vậy một loại chuỗi). Tuy nhiên, trong runtime, string không có phương thức toExponential nên sẽ bị lỗi runtime.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
    }
    console.log(foo.toExponential(2));
}

Ví dụ 4: nếu chúng ta không sử dụng "test is string" (loại vị từ), TypeScript sẽ không thu hẹp loại trong khối được bảo vệ và đoạn mã ví dụ dưới đây sẽ không có lỗi biên dịch nhưng nó sẽ có lỗi thời gian chạy.

function isString(test: any): boolean{
    return typeof test === "string";
}
function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Kết luận là "kiểm tra là chuỗi" (vị từ kiểu) được sử dụng trong thời gian biên dịch để cho các nhà phát triển biết mã sẽ có khả năng xảy ra lỗi thời gian chạy. Đối với javascript, các nhà phát triển sẽ không BIẾT lỗi trong thời gian biên dịch. Đây là lợi thế của việc sử dụng TypeScript.


11

Cách sử dụng duy nhất mà tôi biết là ví dụ của bạn: chỉ định "vị từ kiểu" ( arg is MyType) trong Type Guard do người dùng xác định

Xem Bảo vệ loại do người dùng xác định trong tài liệu tham khảo này

Đây là một tài liệu tham khảo khác


1
Tôi cũng thấy điều này trong tài liệu, thật là một quyết định thiết kế kỳ lạ, trường hợp này hoàn toàn có thể được xử lý bằng cách trả về một kiểu booleanphải không?
benjaminz

2
@benjaminz Điều này có thể đảm bảo rằng đó là câu hỏi của riêng SO nhưng tôi có thể cho bạn xem một ví dụ nhanh về cách chúng khác nhau. Các istừ khóa được thực sự đúc các lỗi loại và có thể gõ bắt sau trong các mã. Xem ví dụ này để biết thêm thông tin.
styfle

@benjaminz Tôi không biết boolean có thể xử lý nó như thế nào. Typecript cần biết rằng hàm mà bạn truyền một đối tượng vào đó hoạt động giống như một bộ bảo vệ kiểu. Nếu nó chỉ trả về kiểu true hoặc false, thì làm cách nào Typecript có thể biết rằng nó thực sự là một kiểu bảo vệ chứ không chỉ một số hàm tùy ý trả về true nếu đối tượng là true. Làm thế nào nó sẽ biết để thu hẹp loại đối tượng? Thứ hai, làm thế nào nó có thể biết loại nào để thu hẹp loại của đối tượng? Điều gì sẽ xảy ra nếu tham số là một trong ba loại? Nó cần biết rằng truetương ứng với một loại cụ thể.
pushkin
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.