Здесь не так много всего, что можно сделать без кода.
На первый взгляд: нет, вы не можете анализировать аргумент универсального типа во время выполнения, поскольку система типов стерта . Во время выполнения вы можете анализировать только значения времени выполнения, такие как фактические объекты, которые вы передаете в конструктор. Во время компиляции вы, вероятно, можете заставить компилятор задавать конкретный логический тип 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
во время выполнения. Есть ли способ справиться с этим? Может быть. Но это не так просто. Вопрос в том, насколько высока вероятность того, что вы столкнетесь с этими случаями, и заботитесь ли вы о них.
В любом случае, надежда, которая имеет смысл и дает вам некоторое направление Удачи!