Вывести тип параметра обратного вызова на основе параметра функции - PullRequest
0 голосов
/ 07 мая 2020
    type SeveralTypes = type0 | type1 | type2;
    function funTypes<T extends SeveralTypes>(info: T, callback: (obj: T extends type2 ? number : string) => void) {
        if (isType0(info)) {
            return callback("passAstring");  // TS Warn: Argument of type '"passAstring"' is not assignable to parameter of type 'T extends boolean ? number : string'

        } else if (isType1(info)) {
            return callback("passAstring"); // TS Warn: Argument of type '"passAstring"' is not assignable to parameter of type 'T extends boolean ? number : string'

        } else {
            return callback(1001); // TS Warn: Argument of type '1001' is not assignable to parameter of type 'T extends boolean ? number : string'
        }
    }

    funTypes(1, (d) => { });       // Typeof d --> string
    funTypes("str", (d) => { });   // Typeof d --> string
    funTypes(false, (d) => { });   // Typeof d --> number

Когда я использую эту функцию, предполагаемый тип обратного вызова параметра правильный. Однако TS указывает на проблемы при назначении параметров. Есть ли другой способ ввести параметры обратного вызова?

1 Ответ

1 голос
/ 07 мая 2020

Здесь есть несколько проблем. Основная из них заключается в том, что сужение одной переменной (info в данном случае) никогда не влияет на тип другой переменной (callback) в этом случае. Существует также проблема, заключающаяся в том, что обычно условные типы, которые все еще содержат неразрешенные параметры типа, обычно трудно рассуждать компилятору, поэтому, поскольку T неизвестен, а ваша функция принимает аргумент, зависящий от T, машинописный текст будет выполнять безопасная вещь и не позволяет вам использовать в качестве параметра либо number, либо string

Обычный способ обойти это - использовать утверждения типа или мой предпочтительный подход, чтобы использовать generi c publi c подпись и более разрешающая подпись реализации (просто имейте в виду, что вы должны убедиться, что logi c в вашем условном типе реплицируется в реализации, здесь нет помощи от компилятора)

type SeveralTypes = type0 | type1 | type2;
function funTypes<T extends SeveralTypes>(info: T, callback: (obj: T extends type2 ? number : string) => void): void
function funTypes(info: SeveralTypes, callback: (obj: number | string) => void) {
  if (isType0(info)) {
    return callback("passAstring");

  } else if (isType1(info)) {
    return callback("passAstring");

  } else {
    return callback(1001); 
  }
}

funTypes(1, (d) => { });       // Typeof d --> string
funTypes("str", (d) => { });   // Typeof d --> string
funTypes(false, (d) => { });   // Typeof d --> number

Ссылка на игровую площадку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...