Điều này được định nghĩa trong đặc tả Chuỗi tùy chọn ECMAScript, vì vậy có lẽ chúng ta nên tham khảo chuỗi tùy chọn khi chúng ta thảo luận về điều này. Có khả năng thực hiện:
const result = a?.b?.c;
Cái dài và ngắn của cái này là nhóm TypeScript đang chờ đặc tả ECMAScript được thắt chặt, do đó việc triển khai của chúng có thể không bị phá vỡ trong tương lai. Nếu họ thực hiện một cái gì đó ngay bây giờ, cuối cùng sẽ cần những thay đổi lớn nếu ECMAScript xác định lại đặc điểm kỹ thuật của họ.
Xem thông số kỹ thuật Chaining tùy chọn
Trong trường hợp thứ gì đó sẽ không bao giờ là JavaScript tiêu chuẩn, nhóm TypeScript có thể triển khai khi họ thấy phù hợp, nhưng đối với các bổ sung ECMAScript trong tương lai, họ muốn duy trì ngữ nghĩa ngay cả khi họ cấp quyền truy cập sớm, vì họ có rất nhiều tính năng khác.
Đường cắt ngắn
Vì vậy, tất cả các toán tử vui nhộn của JavaScripts đều có sẵn, bao gồm các chuyển đổi loại như ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Giải pháp thủ công
Nhưng trở lại câu hỏi. Tôi có một ví dụ khó hiểu về cách bạn có thể làm một điều tương tự trong JavaScript (và do đó là TypeScript) mặc dù tôi chắc chắn không gợi ý nó là một tính năng duyên dáng như tính năng bạn thực sự theo đuổi.
(foo||{}).bar;
Vì vậy, nếu foo
là undefined
kết quả là undefined
và nếu foo
được định nghĩa và có một tài sản có tên bar
mà có một giá trị, kết quả là giá trị đó.
Tôi đặt một ví dụ trên JSFiddle .
Điều này có vẻ khá sơ sài cho các ví dụ dài hơn.
var postCode = ((person||{}).address||{}).postcode;
Chức năng chuỗi
Nếu bạn đang mong muốn một phiên bản ngắn hơn trong khi thông số kỹ thuật vẫn còn trong không khí, tôi sử dụng phương pháp này trong một số trường hợp. Nó đánh giá biểu thức và trả về mặc định nếu chuỗi không thể thỏa mãn hoặc kết thúc null / không xác định (lưu ý điều !=
quan trọng ở đây, chúng tôi không muốn sử dụng !==
vì chúng tôi muốn một chút tung hứng tích cực ở đây).
function chain<T>(exp: () => T, d: T) {
try {
let val = exp();
if (val != null) {
return val;
}
} catch { }
return d;
}
let obj1: { a?: { b?: string }} = {
a: {
b: 'c'
}
};
// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {
a: {}
};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = null;
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));