Как определить тип конструктора на основе переданного класса? - PullRequest
0 голосов
const createObject = (ClassName: any, constructorProps: any) => {
  return new ClassName(constructorProps)
}

interface IProps {
  text: string;
}

class Class {
  constructor({text}: IProps) {
    console.log(text);
  }
}

const obj = createObject(Class, {name: ''}) //no error

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

1 Ответ

0 голосов
/ 12 июля 2020

Использование any по существу требует от компилятора никогда не выдавать вам ошибку; любое значение может быть присвоено типу any, а тип any может быть назначен любому другому типу, поэтому вы можете написать createObject("hello", "goodbye"); и не получить ошибки от компилятора.

Чтобы начать принудительное исполнение некоторая безопасность типов, вы хотите, чтобы аргумент ClassName имел сигнатуру вызова конструктора; то есть это должно быть « newable » с одним аргументом. Что-то вроде ClassName: new (arg: any) => any.

Чтобы представить ограничение, что аргумент ClassName имеет тот же тип, что и constructorProps, функция createObject() должна быть generi c в этом типе. Также поможет, если вы сделаете его generi c в возвращаемом типе конструктора, чтобы компилятор понимал, что получается из createObject().

Вот как я бы написал типизацию:

const createObject = <A, T>(ClassName: new (arg: A) => T, constructorProps: A) => {
    return new ClassName(constructorProps);
}

Теперь вы должны получить более разумное поведение:

const obj = createObject(Class, { name: '' }) // error!
const betterObj = createObject(Class, { text: "" }); // okay
// const betterObj: Class

Компилятор жалуется, если вы не передаете IProps, и он знает, что выходит экземпляр Class.

Хорошо, надеюсь, что это поможет; удачи!

Детская площадка ссылка на код

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