Представьте себе следующий код (детская площадка):
type AvailableTypes = {
'array': Array<any>;
'string': string;
'object': object;
}
class Wrapper<T extends keyof AvailableTypes> {
// Is either array, string or object
private readonly type: T;
// ERROR: Property 'value' has no initializer and is not definitely assigned in the constructor.
private readonly value: AvailableTypes[T];
constructor(type: T) {
this.type = type;
/**
* ERROR:
* TS2322: Type 'never[]' is not assignable to type 'AvailableTypes[T]'.
* Type 'never[]' is not assignable to type 'never'.
*/
switch (type) {
case 'array':
this.value = [];
break;
case 'string':
this.value = '';
break;
case 'object':
this.value = {};
break;
}
}
}
Есть две основные ошибки:
TS2322: Тип 'never []' нельзя назначить типу 'AvailableTypes [T]'.
Тип 'never []' нельзя назначить типу 'never'
Даже если AvailableTypes[T]
всегда разрешается в один из типов, объявленных в AvailableTypes
, где T
является его ключом.
... а также
Свойство value не имеет инициализатора и точно не назначается в конструкторе.
Хотя type
является обязательным и должно быть либо string
, array
, либо object.
Что мне здесь не хватает?
Возможные связанные темы SO:
- Типичное объединение машинописных текстов
- Создать объединение вне интерфейса с помощью общего тега
- TypeScript: использование универсальных типов и типов объединения
Обновлять
(обновление до ответа @jcalz) Должна существовать возможность проверки типа value
на основе свойства type
:
// In the Wrapper class, should work since value can only be an array if type is 'array':
public pushValue(val: unknown) {
if (this.type === 'array') {
this.value.push(val);
}
}