Я пытаюсь создать универсальный класс, в котором тип свойства должен быть либо строкой, либо числом (поскольку он используется в качестве индекса).
Если я попробую что-то вроде кода ниже, он будет жаловаться, что
TS2536: тип «T» нельзя использовать для индекса типа «{}».
export class GenericClass<T> {
public selectionMap: {[id: T]: boolean} = {};
public isSelected(id: T): boolean {
return !!this.selectionMap[id];
}
public toggleSelected(id: T): void {
if (this.isSelected(id)) {
delete this.selectionMap[id];
} else {
this.selectionMap[id] = true;
}
this.onChange();
}
}
В моем случае я всегда знаю, что T будет числом или строкой. Просто не уверен, как записать это, чтобы оставаться типобезопасным.





Почему вы используете дженерики в этом случае? Просто используйте типы, которые вы хотите иметь, или определите тип, который соответствует вашим потребностям:
type Id = number | string;
export class GenericClass {
public selectionMap: {[id: Id]: boolean} = {};
public isSelected(id: Id): boolean {
return !!this.selectionMap[id];
}
public toggleSelected(id: Id): void {
if (this.isSelected(id)) {
delete this.selectionMap[id];
} else {
this.selectionMap[id] = true;
}
this.onChange();
}
}
Хорошее решение, мне в голову не пришло. Но я боюсь, что у него есть одна небольшая проблема. Поскольку этот класс больше похож на util. Мне придется привести результаты каждого метода, вызванного вне этой функции. Потому что мудрая функция всегда будет возвращать число | строка, но я хочу знать, что если я скажу при объявлении, что это используемый номер, он вернет число, а не число | нить. Или я что-то упустил, и это может справиться с этим?
Кстати, я уже ставлю лайк за это, это определенно решение. Просто не уверен, соответствует ли мой точный сценарий.
В этом случае ответ от @ mh377 более уместен. Просто с кодом, который вы разместили, не было необходимости использовать общий класс.
Попробуйте следующее:
export class GenericClass<T = string | number> {}или
export class GenericClass<T extends string, number> {}Кроме того, убедитесь, что типы, которые вы используете для вызова класса, имеют строчные буквы string и number. Смотрите этот блог для получения дополнительной информации.
Спасибо, это имеет смысл, я пробовал что-то подобное, но испортил синтаксис, и это не сработало.
Я только что проверил это, и я все еще получаю ошибки: TS2536: Type 'T' cannot be used to index type '{}'.
Я не вижу код, который вы используете для вызова этого класса, но это примитивы объектов, то есть использование строчных букв «строка» и «число». Подробности смотрите в этом блоге bobbyhadz.com/blog/….
Отвечает ли это на ваш вопрос? TypeScript — как представить сигнатуру индекса в виде универсального типа