Определите тип обратного вызова TypeScript и укажите значение обратного вызова по умолчанию.

У меня возникли проблемы с предоставлением значения обратного вызова по умолчанию И отслеживанием возвращаемого типа этого обратного вызова

В следующем случае a и b оба имеют тип any, но я бы хотел, чтобы они имели возвращаемый тип того, что возвращает callback. В данном случае string и number но в принципе может быть что угодно

const defaultCallback = () => 'Hello World'

function main(callback: () => any = defaultCallback){
  return callback()
}

const a = main(() => 'Foo') <-- Type is any but should be string
const b = main(() => 1000) <-- Type is any but should be number
const c = main() <-- Type is any but should be string

Итак, чтобы решить эту проблему, я попробовал несколько вещей, включая введение дженериков следующим образом. Это определение работает правильно, за исключением того, что я больше не могу указать значение по умолчанию.

const defaultCallback = () => 'Hello World'

function main<T extends any>(callback: () => T = defaultCallback): T {
  return callback()
}

const a = main(() => 'Hello World') <--- Type string 
const b = main(() => 1000) <--- Type number
const c = main() <-- Should be acceptable which requires a default value for callback

Приведенный выше код работает без defaultCallback, но с defaultCallback я получаю:

Type '() => string' is not assignable to type '() => T'. Type 'string' is not assignable to type 'T'. 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'unknown'.(2322)


person Sanborn    schedule 08.03.2021    source источник


Ответы (1)


Вы можете добиться этого с небольшой помощью перегрузок:

const defaultCallback = () => 'Hello World'

function main<R>(callback: () => R): R
function main(): ReturnType<typeof defaultCallback>
function main(callback = defaultCallback) {
    return callback()
}

const a = main(() => 'Foo')    // string
const b = main(() => 1000)     // number
const c = main()               // string

Playground

person captain-yossarian    schedule 08.03.2021