Как определить тип функции с существующим типом в более удобочитаемом виде? - PullRequest
0 голосов
/ 13 февраля 2020

С очень простой и читаемой функцией, такой как:

function signIn(...) {...}

Чтобы определить его тип с существующим определением Action, он становится чем-то не очень читаемым:

const signIn: Action = function (...) {...}

Это много изменений и не очень удобочитаемых, просто чтобы указать, что функция имеет тип Action.

Интересно, есть ли способ не использовать const и сохранить * 1012? * рядом с function? Я понимаю, что могу скопировать существующее определение типа Action и применить его непосредственно к функции, но это не годится для удобства сопровождения - что если оригинальное определение Action изменится?

1 Ответ

3 голосов
/ 13 февраля 2020

Итак, у вас есть такой тип функции:

type MyFunc = (x: string, y: number) => boolean;

, но который нельзя использовать в качестве аннотации для общего объявления функции:

// where to annotate?    
function myFunc(x: string, y: number) {
    return x.length > y; 
}

Было бы неплохо если бы вы могли аннотировать функцию выше каким-либо образом , как, например, следующий гипотетический синтаксис (который в настоящее время не работает):

// do not do this, it doesn't work:
function myFunc: MyFunc (x, y) {
    return x.length > y;
}

К сожалению, в настоящее время это не поддерживается в TypeScript. Однако для этой функции есть открытое предложение: microsoft / TypeScript # 22063 . Не похоже, что по этому вопросу было какое-либо движение, но если вы направитесь туда и дадите ему ?, вы можете очень немного увеличить вероятность его реализации. Или, если ваш вариант использования особенно убедителен и еще не упомянут, вы можете оставить комментарий с его описанием. Реально это никогда не сможет сделать это языком.


Так каковы обходные пути? Очевидным и лучшим из них является изменение объявленной функции на объявленный const типа функции, как вы уже сделали:

const myFunc: MyFunc = function (x, y) {
  return x.length > y;  
}

Вы можете выбрать используйте встроенные служебные типы Parameters<T> и ReturnType<T>, чтобы преобразовать аннотацию самой функции в аннотацию аргументов и возвращаемого типа, но это настолько отвратительно, что я могу Не думаю, что кто-то предпочел бы это предыдущей версии:

function myFunc(...[x, y]: Parameters<MyFunc>): ReturnType<MyFunc> {
    return x.length > y;
}

Другая возможность - попытаться использовать систему типов, чтобы убедиться, что объявленная функция присваивается типу MyFunc в отдельной строке. Если у вас есть вспомогательный тип с именем Extends:

type Extends<T, U extends T> = void;

, тогда вы можете сделать это:

type MyFuncWorks = Extends<MyFunc, typeof myFunc>; // okay
function myFunc(x: string, y: number) {
    return x.length > y;
}

и вы увидите ошибку, если вы измените myFunc на что-то несовместимо:

type MyFuncBroken = Extends<MyFunc, typeof myFunc>; // error!
// number is not boolean ---------> ~~~~~~~~~~~~~
function myFunc(x: string, y: number) {
    return x.length + y; // + instead of <, oops
}

Наименее уродливый обходной путь - все еще типизированный const, поэтому на вашем месте я бы go с этим.


Хорошо, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

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