#javascript #reactjs #typescript
#javascript #reactjs #typescript
Вопрос:
Я пытаюсь создать общую коллекцию для проекта React в Typescript. У меня есть:
class List<T>
{
constructor(data: any){...}
}
который создаст список типа. Я хочу привести его к чему-то, вызвав его с помощью чего-то вроде:
let carList: List<Car> = ...
carList.cast(Car)
если предположить, что Car является классом.
Как мне передать тип класса в качестве параметра для его сопоставления? У меня есть это до сих пор:
public cast(Type: T)
{
this.list = this.list.map(x => x as Type)
}
который не работает, поскольку компилятор жалуется на «Тип ссылается на значение, но используется как тип».
Предположим это.список создается при инициализации списка.
Комментарии:
1. Непонятно, зачем вам нужно что-то подобное. Не могли бы вы объяснить, чего вы пытаетесь достичь?
2. Список предназначался для использования в качестве общего контейнера, который содержал данные вызова базы данных. Затем данные будут проанализированы в список определенного класса. У предыдущей группы, которая работала над проектом, были такие классы, как User, UserList, Submission, SubmissionList и т. Д. Я хотел обобщить их, поскольку казалось, что классы _List были избыточными. Данные API были возвращены с помощью fetch() …затем(apiResponse =>{return new props.responseType(apiResponse)}, где responseType имеет тип {new (data:any): T} .
Ответ №1:
Тип не существует в среде выполнения JS, поэтому вы не можете передать его в качестве параметра функции.
Обычно, чтобы преобразовать ваш список в список во время выполнения, вы должны проверить, возможно ли это. Итак, вам нужно проверить все содержимое списка, и это может быть дорого с точки зрения производительности
type Guard<T> = (item: any) => item is T;
// https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
class List<T> {
constructor(
public data: T[]
) { }
static getUserGuard<T>(itemGuard: Guard<T>): Guard<List<T>> {
return (list: List<any>): list is List<T> => list.data.every(itemGuard)
}
}
// and list usage
const lists: List<any>[] = [
new List<number>([42]),
new List<string>(['foo']),
]
const isNumber = (v: any): v is number => typeof v === 'number';
const isString = (v: any): v is string => typeof v === 'string';
// some code with random lists
const doSomething = (lists: List<any>[]) => {
for (const list of lists) {
if (List.getUserGuard(isNumber)(list)) {
// list is List<number> there
} else if (List.getUserGuard(isString)(list)) {
// list is List<string> there
} else {
// list has some other type there
}
}
}
Также вы можете проверить мои классы, но не по содержимому
class List<T> {
constructor(
public data: T[]
) { }
}
class NumbersList extends List<number> {
}
class StringList extends List<string> {
}
// some code with random lists
const doSomething = (lists: List<any>[]) => {
for (const list of lists) {
if (list instanceof NumbersList) {
// list is List<number> there
} else if (list instanceof StringList) {
// list is List<string> there
} else {
// list has some other type there
}
}
}