Обнаружение, имеет ли аргумент универсального типа свойство id? - PullRequest
0 голосов
/ 01 сентября 2018

Я разрабатываю общий класс Slice<E>, который представляет часть экземпляров набора экземпляров. Например, если у нас есть Todo экземпляров, то срез может представлять все те, которые завершены.

Если класс Todo имеет свойство id, мы хотели бы установить hasID на true для экземпляра Slice, чтобы мы могли также индексировать экземпляр Slice с помощью id. Есть ли способ обнаружить во время выполнения, имеет ли универсальный аргумент и свойство id?

1 Ответ

0 голосов
/ 01 сентября 2018

Здесь не так много всего, что можно сделать без кода.

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

Давайте попробуем. Вот эскиз возможного решения:

class Slice<E> {
  instances: E[]
  hasID: E extends {id: any} ? true : false;
  constructor(firstInstance: E, ...restInstances: E[]) {
    this.hasID = 'id' in firstInstance as Slice<E>['hasID'];    
    this.instances = [firstInstance, ...restInstances];
  }
}

Свойству hasID присваивается условный тип , который оценивает параметр типа E и возвращает true, если существует E['id'], и false в противном случае.

Конструктор принимает хотя бы один параметр типа E, первый из которых анализируется во время выполнения для свойства id, чтобы установить значение hasID времени выполнения.

Посмотрим, работает ли он:

const sliceOne = new Slice({a: 1}, {a: 2});
sliceOne.hasID // false at compile time and runtime

const sliceTwo = new Slice({id: 1}, {id: 2});
sliceTwo.hasID // true at compile time and runtime

Хорошо выглядит. Тем не менее, существуют крайние случаи, о которых вам может потребоваться беспокоиться, например:

declare const notSure: object;
const oopsie = new Slice(notSure);
oopsie.hasID; // false at compile time, maybe true at runtime!

Компилятор не может проверить, что object имеет свойство id, поэтому он дает hasID тип false. Но, конечно, object может иметь свойство id, поэтому, возможно, hasID будет true во время выполнения. Есть ли способ справиться с этим? Может быть. Но это не так просто. Вопрос в том, насколько высока вероятность того, что вы столкнетесь с этими случаями, и заботитесь ли вы о них.

В любом случае, надежда, которая имеет смысл и дает вам некоторое направление Удачи!

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