Типы typeof
Оператор типов typeof в Flow извлекает тип Flow для значения, поэтому его можно использовать в аннотации типа.
let size = 42; let other: typeof size = 100; // type is number
Когда это использовать
Используйте typeof, чтобы получить тип из существующего значения, вместо того чтобы записывать его вручную. Это полезно, если модуль экспортирует значение, но не его тип, или если вы хотите, чтобы аннотации соответствовали выведенному типу переменной. Если тип уже доступен как именованный экспорт, предпочтительнее импортировать его напрямую.
Синтаксис типа typeof
Оператор typeof возвращает тип Flow для указанного значения, чтобы использовать его как тип.
let num1 = 42; let num2: typeof num1 = 3.14; // Works! let num3: typeof num1 = 'world'; // Error! let bool1 = true; let bool2: typeof bool1 = false; // Works! let bool3: typeof bool1 = 42; // Error! let str1 = 'hello'; let str2: typeof str1 = 'world'; // Works! let str3: typeof str1 = false; // Error!
С typeof можно использовать любое значение, если сам аргумент является переменной или обращением к члену:
let obj1 = {foo: 1, bar: true, baz: 'three'};
let obj2: typeof obj1 = {foo: 42, bar: false, baz: 'hello'};
let num: typeof obj1.foo = 1;
let arr1 = [1, 2, 3];
let arr2: typeof arr1 = [3, 2, 1];
type T = typeof {a: 1}; // Error
typeof наследует поведение вывода типов
Используя typeof, вы берёте результат вывода типов Flow и задаёте его как тип. Это может быть очень полезно, но также может привести к неожиданным результатам.
Например, при использовании литеральных значений в Flow их выведенный тип — это примитив, к которому они относятся. Так, для числа 42 выводится тип number. Это можно увидеть, если использовать typeof.
let num1 = 42; let num2: typeof num1 = 3.14; // Works! let bool1 = true; let bool2: typeof bool1 = false; // Works! let str1 = 'hello'; let str2: typeof str1 = 'world'; // Works!
Однако это происходит только с выведенным типом. Если указать литеральный тип, он будет использован в typeof.
let num1: 42 = 42; let num2: typeof num1 = 3.14; // Error! let bool1: true = true; let bool2: typeof bool1 = false; // Error! let str1: 'hello' = 'hello'; let str2: typeof str1 = 'world'; // Error!
typeof наследует поведение других типов
В Flow есть множество разных типов, и некоторые из них ведут себя не так, как другие. Эти различия уместны для соответствующего типа, но не для остальных.
Используя typeof, вы вставляете другой тип со всем его поведением. Из-за этого typeof может показаться непоследовательным, хотя на самом деле это не так.
Например, если использовать typeof с классом, нужно помнить, что типы классов являются номинальными, а не структурными. Поэтому два класса с совершенно одинаковой структурой не считаются эквивалентными.
class MyClass {
method(val: number) { /* ... */ }
}
class YourClass {
method(val: number) { /* ... */ }
}
let test1: typeof MyClass = YourClass; // Error!
let test2: typeof MyClass = MyClass; // Works! Отличия от оператора typeof времени выполнения
Оператор typeof в JavaScript во время выполнения возвращает строку, например "number" или "object", но не может различать многие типы — например, объекты, массивы и null для всех возвращают "object":
typeof {foo: true} === 'object';
typeof [true, false] === 'object';
typeof null === 'object'; Оператор typeof в Flow действует на уровне типов и предоставляет полный тип Flow для значения, сохраняя его точную структуру. Он не используется во время выполнения — он существует только в аннотациях типов.
См. также
-
Классы —
typeofчасто используется с классами, чтобы ссылаться на тип значения класса (а не экземпляра) -
Модули —
typeofимпортов для получения типа импортированного значения -
Номинальная и структурная типизация —
typeofс классами сохраняет поведение номинальной типизации
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/types/typeof