"невідомий" проти "будь-який"


190

TypeScript 3.0 представляє unknownтип відповідно до їх вікі:

Невідомо тепер зарезервоване ім'я типу, оскільки це вбудований тип. Залежно від наміченого використання невідомого, ви можете повністю видалити декларацію (надаючи перевагу нещодавно введеному невідомому типу) або перейменувати її на щось інше.

У чому різниця між unknownі any? Коли ми повинні використовувати unknownбільше any?

Відповіді:


233

Більше про це можна прочитати unknownв PR або RC-оголошенні , але суть цього:

[..] невідомо, який є захистом від типу будь-якого. Все, що можна віднести до невідомого, але невідоме не призначається нічому, окрім себе та будь-якому, без твердження типу чи звуження, заснованого на контрольному потоці. Так само жодні операції з невідомою не допускаються без попереднього затвердження або звуження до більш конкретного типу.

Кілька прикладів:

let vAny: any = 10;          // We can assign anthing to any
let vUnknown: unknown =  10; // We can assign anthing to unknown just like any 


let s1: string = vAny;     // Any is assigable to anything 
let s2: string = vUnknown; // Invalid we can't assign vUnknown to any other type (without an explicit assertion)

vAny.method();     // ok anything goes with any
vUnknown.method(); // not ok, we don't know anything about this variable

Пропоноване використання:

Часто ми хочемо описати тип найменш здатного в TypeScript. Це корисно для API, які хочуть сигналізувати "це може бути будь-яке значення, тому перед тим, як використовувати його, потрібно виконати певний тип перевірки". Це змушує користувачів безпечно вводити повернені значення.


35
Кожен, хто приходить з фоном C #, anyсхожий dynamicі unknownсхожий object. Мені подобається, unknownоскільки це просто більш безпечний тип. Хоча заплутані імена.
nawfal

1
Я не знаю, що це справедливо для порівняння unknownі object@nawfal, хоча я думаю, що я бачу, що ви отримуєте в плані протиріччя та коваріації (наприклад, будь-який об'єкт можна віднести до типу, objectхоча для unknownбудь-якого об'єкта чи примітиву може бути призначений - аналогічно unknownможе бути призначено до anyсебе або objectможе бути призначене для dynamicсебе). У бічній записці мені незрозуміло, чому документи TS називають unknownтоп-типом, оскільки він насправді не містить усіх типів ¯_ (ツ) _ / ¯
Йорданія,

38

Різниця між невідомим і будь-яким описується як:

Начебто anyбудь-яка цінність присвоюється unknown; однак, на відміну від цього any, ви не можете отримати доступ до будь-яких властивостей на значеннях з типом unknown, а також не можете викликати / побудувати їх. Крім того, значення типу unknownможна призначати лише unknownабо any.

Щоб відповісти на ваше запитання про те, коли слід використовувати в unknownпротягом any:

Це корисно для API, які хочуть сигналізувати "це може бути будь-яке значення, тому перед тим, як використовувати його, потрібно виконати певний тип перевірки". Це змушує користувачів безпечно вводити повернені значення.

Погляньте на оголошення TypeScript 3.0 для прикладів перевірки типу змінної типу unknownта більш детального пояснення.


21

any тип:

anyТип представляє всі можливі значення JS. Кожен тип можна віднести до типу any. Тому тип anyє універсальним супертипом типової системи. Компілятор TS дозволить проводити будь-яку операцію з набраними значеннями any. Наприклад:

let myVar: any;

myVar[0];
myVar();
myVar.length;
new myVar();

У багатьох випадках це занадто поблажливо до компілятора TS. тобто це дозволить операціям, про які ми могли б знати, що призведе до помилки виконання.

unknown тип:

unknownТип представляє (як any) всі можливі значення JS. Кожен тип можна віднести до типу unknown. Тому тип unknown- це ще один універсальний супертип типу типів (поряд any). Однак компілятор TS не дозволить жодної операції над набраними значеннями unknown. Крім того, unknownтип присвоюється тільки типу any. Приклад уточнить це:

let myVar: unknown;

let myVar1: unknown = myVar;   // No error
let myVar2: any = myVar;       // No error
let myVar3: boolean = myVar;   // Type 'unknown' is not assignable to type 'boolean'

// The following operations on myVar all give the error:
// Object is of type 'unknown'
myVar[0];
myVar();
myVar.length;
new myVar();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.