вывод общего типа typescript в функции более высокого порядка

#typescript #generics

#typescript #общие сведения

Вопрос:

 function generate<P extends object>(init: (p: P) => void) {
  return function (p: P): P {
    init(p)
    return p
  }
}

const g = generate(function AAA<T>(p: T) {
  console.log(p)
})

const result = g({
  x: 1
})

result.x // TS2339: Property 'x' does not exist on type '{}'.
  

generate Функция является функцией более высокого порядка, и, похоже, typescript не может определить общий тип P .

Как я могу сделать generate способным принимать общую типизированную функцию в качестве параметра?

Комментарии:

1. В этом блоге я обнаружил новую функцию в Typescript 3.4 rc, которая называется «Распространяемые аргументы универсального типа»: devblogs.microsoft.com/typescript/announcing-typescript-3-4-rc . Это именно то, чего я хочу!

Ответ №1:

Typescript 3.4 вносит огромные улучшения в обработку пересылки параметров универсального типа. Вы можете прочитать подробности здесь.

Хотя ваш код также не будет работать так, как в 3.4, мы можем заставить его работать, если изменим init функцию, чтобы она принимала общий аргумент кортежа. Это приведет к запуску пересылки параметров типа:

 function generate<A extends [any]>(init: (...p: A) => void) {
    return function (...p: A): A[0] {
        init(...p)
        return p
    }
}

const g = generate(function AAA<T>(p: T) {
    console.log(p)
})

const result = g({
    x: 1
})

result.x // ok now
  

Вы можете протестировать этот код самостоятельно, если запустите npm install typescript@next .

Комментарии:

1. Можете ли вы объяснить, что вы подразумеваете под перенаправлением параметров типа?

2. @Wex <T> на функцию параметра перенаправляется возврат generate функции. Параметр type в g нигде явно не был определен, но вместо этого исходит из того факта, что init он был универсальным.