#typescript #typing
#typescript #ввод
Вопрос:
В настоящее время у меня есть несколько следующих типов:
type Value = boolean | number | string
class Struct<T extends Value[] = Value[]> {
constructor(fmt: string) { }
pack(...args: T): Buffer { }
}
Я хотел бы знать, как заменить <???>
список, Value[]
используемый каждым Struct
, переданный конструктору в следующем фрагменте:
class StructConcat<T extends Struct[]> {
constructor(...structs: T) { }
pack(...args_list: <???>) { }
}
// example:
const a: HeadStruct = new Struct<[number]>('<I')
const b: VectorStruct = new Struct<[number, number, number]>('<3f')
const concat = new StructConcat(a, b)
В конечном счете, StructConcat.pack
функция должна быть ограничена таким образом, чтобы:
concat.pack([1], [2, 3, 4])
Пока лучшее, что я мог сделать, это: (T[number] extends Struct<infer K> ? K : never)[]
но в приведенном выше сценарии он выводит ([number] | [number, number, number])[]
то, что близко, но все еще не: [[number], [number, number, number]]
.
Допускает ли система набора текста TypeScript такую вещь?
Ответ №1:
Вы можете использовать кортежи в сопоставленных типах, начиная с версии 3.1:
type Value = boolean | number | string
class Struct<T extends Value[] = Value[]> {
constructor(fmt: string) { }
pack(...args: T): Buffer { }
}
type ExtractValueFromStruct<T> = T extends Struct<infer V> ? V : never
type MapStructTuple<T extends Struct[]> = {
[P in keyof T]: ExtractValueFromStruct<T[P]>
}
class StructConcat<T extends Struct[]> {
constructor(...structs: T) { }
pack(...args_list: MapStructTuple<T>) { }
}
// example:
const a= new Struct<[number]>('<I')
const b= new Struct<[number, number, number]>('<3f')
const concat = new StructConcat(a, b)
concat.pack([1], [1, 2, 3])
concat.pack([1], [1, 2, 3, 4]) // err
Комментарии:
1. @WKnight02 рад помочь 🙂