«неизвестно» против «любой»


190

TypeScript 3.0 вводит unknownтип в соответствии с их вики:

unknown теперь является зарезервированным именем типа, так как теперь это встроенный тип. В зависимости от предполагаемого использования неизвестного, вы можете полностью удалить объявление (в пользу вновь введенного неизвестного типа) или переименовать его в другое.

Какая разница между unknownа any? Когда мы должны использовать unknownболее any?

Ответы:


235

Вы можете прочитать больше об этом 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, которые хотят сигнализировать «это может быть любое значение, поэтому вы должны выполнить какой-либо тип проверки перед использованием». Это заставляет пользователей безопасно анализировать возвращаемые значения.


36
Любой, кто приходит из 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.