Похоже, вы смешиваете JavaScript оператор typeof
с TypeScript - оба не выполняют sh одно и то же.
В JS, typeof something
будет вычисляться как простой строка времени выполнения (например, 'number'
, 'string'
, 'object'
...), которую ваше приложение затем может использовать для сравнения. Это не то, что вам нужно здесь.
В TS typeof
помогает вам извлечь подразумеваемый тип TS *1012* из переменной JS в качестве значимой структуры - истинной TypeScript type . Это полезно, когда вы хотите определить сложные типы TS из существующего JS кода.
const a = Object.freeze({
REMOVE_ITEM: 'REMOVE_ITEM',
ADD_ITEM: 'ADD_ITEM'
});
// ^ to TypeScript, this is similar to this type:
// Readonly<{ REMOVE_ITEM: string; ADD_ITEM: string; }>
Чтобы извлечь подразумеваемый тип:
type AObject = typeof a;
// Readonly<{ REMOVE_ITEM: string; ADD_ITEM: string; }>
Чтобы иметь определения типов, соответствующие ключам в этом объекте используйте keyof
при определении типа TS, соответствующего любой клавише:
type AKey = keyof AObject;
// "REMOVE_ITEM" | "ADD_ITEM"
// or in a strictly similar way:
type AKey = keyof typeof a;
// "REMOVE_ITEM" | "ADD_ITEM"
Теперь вернемся к коду времени выполнения. После того, как вы извлекли тип AKey
, соответствующий ключам a
, вы можете обеспечить согласованность типов для некоторых JS значений и аргументов, где это необходимо:
function createActionObject(actionType: AKey) {
return { type: actionType };
}
const action1 = createActionObject('REMOVE_ITEM');
// compiles and works as expected
const action2 = createActionObject('SOME_BAD_KEYNAME');
// TypeScript Error ->
// Type '"SOME_BAD_KEYNAME"' is not assignable to type '"REMOVE_ITEM" | "ADD_ITEM"'
Наконец, , вы не можете «назначить» типы TS для переменной JS, вы можете просто описать, как должна выглядеть переменная JS, поэтому TypeScript проверяет ее, прежде чем в конечном итоге перейти к JS. Если вы попытались получить массив, в котором перечислены все ключи в a
, вам нужно использовать традиционные методы JS:
const b = Object.keys(a);
// to JavaScript: will be ['REMOVE_ITEM', 'ADD_ITEM']
// to TypeScript: string[]
// or, to get stronger typings for `b` rather than just `string[]`:
const b = Object.keys(a) as (keyof typeof a)[];
// to JavaScript: will be ['REMOVE_ITEM', 'ADD_ITEM']
// to TypeScript: ('REMOVE_ITEM' | 'ADD_ITEM')[]