Обобщение Typescript: как обеспечить соответствие аргументов функций друг другу? - PullRequest
0 голосов
/ 23 марта 2020

Я хочу иметь функцию с аргументом определенного типа и «совпадающим» литералом. Как я могу это сделать?

class T1 {
  val: string = "abc"
}
class T2 {
  val: number = 123
}
type TType = 'T1' | 'T2'

// I want to make this generic so the args have to "match"
function foo(ttype: TType, arg: T1 | T2) {
  console.log(`${ttype}: arg.val`)
}

foo('T1', new T1)
foo('T2', new T2)
foo('T1', new T2) // I want this to be a compile-time error

Я бы хотел, чтобы код требовал, чтобы при передаче 'T1' как ttype в качестве второго аргумента использовался объект типа T1, и наоборот. Мне не нужны две версии функции, если я могу избежать этого (не хочу копировать тело) - просто тип spe c, который говорит «либо литерал T1 и T1, или * 1006». * буквально Т2 и Т2 ". Я рад установить сопоставления вручную - мне не нужно получать имя класса из строкового литерала. Просто не знаю, как подойти к этому в Typescript.

1 Ответ

4 голосов
/ 23 марта 2020

Простой подход заключается в использовании перегрузок

function foo(ttype: "T1", arg: T1): void
function foo(ttype: "T2", arg: T2): void
function foo(ttype: TType, arg: T1 | T2) {
  console.log(`${ttype}: arg.val`)
}

Playground Link

Вы также можете go с универсальной c функцией с интерфейсом отображения , но для примера, который, вероятно, будет излишним:

type TMap = {
  "T1": T1
  "T2": T2
}
// I want to make this generic so the args have to "match"
function foo<T extends TType>(ttype: T, arg: TMap[T]): void
function foo(ttype: TType, arg: T1 | T2) {
  console.log(`${ttype}: arg.val`)
}

Playground Link

...