TypeScript тип объединения generi c параметр - PullRequest
1 голос
/ 04 августа 2020

Итак, у меня есть следующий образец кода:

interface MyInterface<T> {
  myFunc(value: T): void;
}

class MyImplementation implements MyInterface<number> {
  myFunc(value: number): void {
    console.log(value / 2);
  }
}

function myTest(): MyInterface<number|string> {
  return new MyImplementation(); // doesn't look quite right
}

myTest().myFunc("I am not a number"); // outputs NaN

Я не могу понять, почему машинописный текст позволяет мне возвращать MyImplementation в место MyInterface . Я понимаю, что мы хотим, чтобы номер можно было присвоить номеру | строка , но, конечно, не для общих c параметров.

1 Ответ

1 голос
/ 04 августа 2020

Этот пример также работает без дженериков:

interface MyInterface {
  myFunc(value: number): void;
}

interface MyInterface2 {
  myFunc(value: number|string): void;
}

class MyImplementation implements MyInterface {
  myFunc(value: number): void {
    console.log(value / 2);
  }
}

function myTest(): MyInterface2 {
  return new MyImplementation(); // doesn't look quite right
}

myTest().myFunc("I am not a number"); // outputs NaN

Типографский сценарий был разработан так, чтобы иметь некоторую несостоятельность в системе типов, как описано здесь: https://www.typescriptlang.org/docs/handbook/type-compatibility.html

To Чтобы обойти это, вы можете определить свой интерфейс следующим образом:

interface MyInterface<T> {
  myFunc: (value: T) => void;
}

А затем включить strictFunctionTypes или strict в tsconfig.json.

См. также: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html

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

...