Интерфейс с условными свойствами - PullRequest
0 голосов
/ 28 января 2019

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

interface HasNoName {
  hasName: false;
}

interface HasName {
  hasName: true;
  name: string;
}

type MySpecialType = HasNoName | HasName;

Есть ли способ написать MySpecialType в качестве интерфейса?Это должен быть интерфейс, потому что я хочу, чтобы класс его реализовал.Я не могу написать:

interface MySpecialType extends HasNoName, HasName {}

, так как я получаю сообщение об ошибке:

«Именованное свойство hasName типов« HasName »и« HasNoName »не идентичны».

1 Ответ

0 голосов
/ 28 января 2019

Вы не можете сделать интерфейс из типа объединения.Но вы можете создавать классы, которые действуют так, как будто они реализуют типы объединения, если вам это действительно нужно ... но это включает в себя некоторые утверждения типа , потому что компилятор не может легко проверить, что вы делаете.

В качестве примера: создайте класс, который реализует ближайшую вещь, которую вы на самом деле можете реализовать ... что-то вроде {hasName: boolean, name?: string}:

class _MySpecialClass {
  public hasName: boolean;
  public name?: string;
  public constructor();
  public constructor(name: string);
  public constructor(name?: string) {
    this.hasName = (typeof name !== 'undefined');
    this.name = name;
  }
}

У этого есть перегруженный конструктор, который отмечаетразница между HasName и HasNoName.

Затем создайте именованное значение и именованный тип с именем MySpecialClass, который объявлен так, как вам нужно.Именованный тип MySpecialClass - это просто объединение MySpecialType в этом примере, тогда как именованное значение MySpecialClass - это конструктор _MySpecialClass, который действует так, как вы хотите.

type MySpecialClass = MySpecialType;    
const MySpecialClass = _MySpecialClass as {      
  new(name: string): HasName;
  new(): HasNoName;
};

И тестирование с использованиемэто:

const mySpecialInstance: MySpecialClass = 
  Math.random()<0.5 ? new MySpecialClass() : new MySpecialClass("Fred");

Ну, это выглядит хорошо.У этого есть некоторые бородавки, но в зависимости от Вашего варианта использования это могло бы работать на Вас.Надеюсь, поможет.Удачи!

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