Свойство функции интерфейса TypeScript: в чем разница? - PullRequest
1 голос
/ 12 марта 2020

Может кто-нибудь объяснить, почему в этом коде назначение константы типа InterfaceA работает, но присвоение константы типа InterfaceB выдает ошибку:

interface InterfaceA {
  doSomething (data: object): boolean;
}

interface InterfaceB {
  doSomething: (data: object) => boolean;
}

function doIt (data: { type: string; }): boolean {
    return true;
}

const A: InterfaceA = {
    doSomething: doIt
};
const B: InterfaceB = {
    doSomething: doIt
};

Для онлайн-демонстрации см. : http://www.typescriptlang.org/play/index.html?ssl=19&ssc=1&pln=1&pc=1#code / JYOwLgpgTgZghgYwgAgJLmvJBBZBvAWAChlkATAewGUKBbCMAC1AHNkAKMuMOALmQoAjAFYQEYAJT9BFCgBsIcEAG5iAX2LFQkWIhTodWCACF8xUpRr0mrfp258BIsZOQBeAHzIZ8xSvWaRDAAriDiwBQg5BSoYBxcPPx4yGAAngAOEPwAzmBQrMrIalLesgpKZkQAkFAMwVBRecEQqkQaRMQIkbnI2PwGmHq4bpVVlnQMzCAs-JSx6q1dID3G-Ri6SKYjhNXj1lMz0fNtrUA

1008 * Для меня оба интерфейса определяют то же самое, только обозначение отличается 1010 * Если это не ошибка. в TypeScript, и есть реальная причина, тогда давайте перейдем ко второму вопросу: мне нужно указать, что doSomething является необязательным и может быть либо функцией, либо RegExp:
interface InterfaceB {
  doSomething?: ((data: object) => boolean) | RegExp;
}`

Как Могу ли я достичь этого с помощью обозначения InterfaceA?

1 Ответ

2 голосов
/ 12 марта 2020

1.) Существует различие между методом и объявлением свойства функции:

interface InterfaceA {
  doSomething(data: object): boolean; // method declaration
}

interface InterfaceB {
  doSomething: (data: object) => boolean; // function as property declaration
}

2.) TS 2.6 введены строгие типы функций, которые обеспечивают более строгую типизацию и многое другое звук функции:

Позиции параметров в типе функции --strictFunctionTypes проверяются , а не бивариантно . более строгая проверка применяется к всем типам функций , кроме тех, которые исходят из объявлений методов или конструкторов .

В общем, это хорошо. В вашем примере InterfaceB имеет следующий контракт: «Каждая функция, которая может работать с общим object, совместима». Но вы хотите назначить функцию, которая ожидает Speci c объектов типа { type: string; } в качестве входных данных. Так что клиент, который использует InterfaceB, считает, что достаточно передать object, но реализация doIt хочет чего-то более конкретного, поэтому вы по праву получаете эту ошибку.

И почему ошибка не возникает случаются с InterfaceA?

Напротив, методы , такие как doIt в InterfaceA, исключены из strictFunctionTypes по практическим соображениям. Разработчики решили, что система типов не слишком pendanti c со встроенными методами Array et c. чтобы иметь разумный баланс между правильностью и производительностью.

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

interface InterfaceB {
  doSomething: ((data: { type: string; }) => boolean) | RegExp;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...