Инструменты пользователя

Инструменты сайта


typescript:types:unknown

Unknown

Тип Unknown является типобезопасным аналогом типа any и представлен в виде литерала unknown. Все типы совместимы с типом unknown, в то время как сам тип unknown совместим только с самим собой и типом any.

class TypeSystem {
  static unknown: unknown;
 
  static any: any = TypeSystem.unknown; // Ok
  static number: number = TypeSystem.unknown; // Error
  static string: string = TypeSystem.unknown; // Error
  static boolean: boolean = TypeSystem.unknown; // Error
  static null: null = TypeSystem.unknown; // Error
  static undefined: undefined = TypeSystem.unknown; // Error
  static void: void = TypeSystem.unknown; // Error
  static never: never = TypeSystem.unknown; // Error
}
 
TypeSystem.unknown = TypeSystem.any; // Ok
TypeSystem.unknown = TypeSystem.number; // Ok
TypeSystem.unknown = TypeSystem.string; // Ok
TypeSystem.unknown = TypeSystem.boolean; // Ok
TypeSystem.unknown = TypeSystem.null; // Ok
TypeSystem.unknown = TypeSystem.undefined; // Ok
TypeSystem.unknown = TypeSystem.void; // Ok
TypeSystem.unknown = TypeSystem.unknown; // Ok

Кроме того, над типом unknown запрещено выполнение каких-либо операций.

let v0: any;
v0.a = 5; // Ok
v0.a = ''; // Ok
v0(); // Ok
 
let v1: unknown = v0; // Ok
v1.a = 5; // Error
v1.a = ''; // Error
v1(); // Error

Если тип unknown составляет тип пересечение (intersection), то он будет перекрыт всеми типами.

type T0 = any & unknown; // type T0 = any
type T1 = number & unknown; // type T1 = number
type T2 = string & unknown; // type T2 = string
type T3 = boolean & unknown; // type T3 = boolean
type T4 = null & unknown; // type T4 = null
type T5 = undefined & unknown; // type T5 = undefined
type T6 = void & unknown; // type T6 = void
type T7 = never & unknown; // type T7 = never
type T8<T> = T & unknown; // type T8 = T
type T9 = unknown & unknown; // type T9 = unknown

Если тип unknown составляет тип объединение (union), то он перекроет все типы, за исключением типа any.

type T0 = any | unknown; // type T0 = any
type T1 = number | unknown; // type T1 = unknown
type T2 = string | unknown; // type T2 = unknown
type T3 = boolean | unknown; // type T3 = unknown
type T4 = null | unknown; // type T4 = unknown
type T5 = undefined | unknown; // type T5 = unknown
type T6 = void | unknown; // type T6 = unknown
type T7 = never | unknown; // type T7 = unknown
type T8<T> = T | unknown; // type T8 = unknown
type T9 = unknown | unknown; // type T9 = unknown

Помимо этого, запрос ключей (keyof) для типа unknown возвращает тип never.

type T0 = keyof number; // type T0 = "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"
type T1 = keyof any; // type T1 = string | number | symbol
type T2 = keyof unknown; // type T2 = never

Тип unknown позволяется использовать только в операциях равенства ===, ==, !== и != и в операциях с логическими операторами &&, || и !.

let v0: unknown = 5;
 
let v1 = 5 === v0; // Ok
let v2 = 5 !== v0; // Ok
let v3 = 5 > v0; // Error
let v4 = 5 < v0; // Error
let v5 = 5 >= v0; // Error
let v6 = 5 <= v0; // Error
let v7 = 5 - v0; // Error
let v8 = 5 * v0; // Error
let v9 = 5 / v0; // Error
let v10 = ++v0; // Error
let v11 = --v0; // Error
let v12 = v0++; // Error
let v13 = v0--; // Error
 
let v14 = 5 && v0; // Ok, let v14: unknown
let v15 = 5 || v0; // Ok, let v15: number
let v16 = v0 || 5; // Ok, let v16: unknown
let v17 = !v0; // Ok, let v17: boolean

Также стоит упомянуть, что функция, у которой возвращаемый тип принадлежит к типу unknown, может не возвращать значение явно.

function f0(): unknown {
  return; // Ok
}
 
function f1(): number {
  return; // Error
}
 
let v = f0(); // Ok, let v: unknown

При активной опции –strictPropertyInitialization принадлежащие к типу unknown поля не нуждаются в инициализации.

class T {
  f0: unknown; // Ok
  f1: number; // Error
  f2: number = 5; // Ok
}

Если в определении типа данных участвует сопоставленный тип (Mapped Type), которому в качестве аргумента типа передается тип unknown, то такой сопоставленный тип будет выведен как объектный тип {}. Поскольку сопоставленные типы (Mapped Types), псевдонимы типов (types), а также обобщения (Generics<>) будут рассмотрены позднее, то стоит просто помнить об этом факте и повторно прочесть написанное при необходимости.

type MappedType<T> = {
  [K in keyof T]: T;
};
 
type T0 = MappedType<number>; // type T0 = number
type T1 = MappedType<any>; // type T1 = { [x: string]: any; }

type T2 = MappedType<unknown>; type T2 = {}

typescript/types/unknown.txt · Последние изменения: 2023/01/29 20:29 — werwolf