Как мне аннотировать тип параметра как «любое значение объекта»?
class ExampleClass {
private static readonly MODES = {
DEVELOPMENT: 0,
PRODUCTION: 1,
TEST: 2
}
// Any Value of ExampleClass.MODES
constructor(mode: MODE[?]) {
}
}
В этом случае значения 0
, 1
, 2
не имеют смысла, если использовать enum
, но насколько мне известно, мы не можем использовать enum
как поле класса. Итак, давайте рассмотрим случай some value of object
в этом вопросе.
2 ответа
Томаш был очень близок, но давайте дадим полный ответ. Чтобы получить тип значений typeof MODES
, просто проиндексируйте его по типу всех его ключей.
type ValueOf<T> = T[keyof T];
// Prevent widening of the types of the constants to `number`.
function asLiterals<T extends number, U extends { [n: string]: T }>(arg: U) {
return arg;
}
class ExampleClass {
private static readonly MODES = asLiterals({
DEVELOPMENT: 0,
PRODUCTION: 1,
TEST: 2
});
// Any Value of ExampleClass.MODES
constructor(mode: ValueOf<typeof ExampleClass.MODES>) {
}
}
Вы можете использовать в этом конкретном случае type
:
type myType = 'DEVELOPMENT' | 'PRODUCTION' | 'TEST'
class someClass {
// Any Value of ExampleClass.MODES
constructor(mode: myType ) { }
}
Для более сложных сценариев обратитесь к приведенной ниже документации TypeScript в форме фрагмента кода, где K extends keyof T
используется для гарантии того, что в качестве аргументов функции передаются только значения, являющиеся частью спецификации объекта:
function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
interface Person {
name: string;
age: number;
}
let person: Person = {
name: 'Jarid',
age: 35
};
let strings: string[] = pluck(person, ['name']); // ok, string[]
Вышеупомянутые могут быть частью вашей служебной службы и универсально использоваться в нескольких конструкторах, типы которых вы хотите обеспечить.
Или даже заключите значения, которые вы хотите защитить, в отдельный класс и напрямую используйте keyof
:
class A {
prop1: 1;
prop2: 2;
}
class TestClass {
constructor(key: keyof A) {
}
}
let tc1 = new TestClass('prop1')
let tc2 = new TestClass('whoops') // Error
И насколько я понимаю ваше намерение, вы хотите иметь что-то больше вроде valueof
, чем keyof
. Если да, то да, перечисления и типы - это то, на что вам следует обратить внимание ИМХО.
Похожие вопросы
Новые вопросы
typescript
TypeScript - это типизированный надмножество JavaScript, которое компилируется в простой JavaScript. Он добавляет в JavaScript дополнительные типы, классы, интерфейсы и модули. Этот тег предназначен для вопросов, относящихся к TypeScript. Он не используется для ответов на общие вопросы по JavaScript.