#typescript #class #methods #prototype #factory
#typescript #класс #методы #прототип #фабрика
Вопрос:
Я немного поработал над этой проблемой и решил, что в конце концов пойму или найду достойное объяснение. Я прочитал много статей в руководстве по TS, поискал в Google () и искал SO, но пока не нашел ответа.
Мне нужно знать, как правильно и полностью ввести прототипный метод в классе / интерфейсе TS.
interface UploadFileInterface {
contentSizes: number[];
chunks: [];
chunksDone: number;
getChunkLength: (id: number) => void;
name: string;
size: string;
chunksQuantity: number;
}
class UploadedFile implements UploadFileInterface {
contentSizes: Array<number> = [];
chunks: [] = [];
chunksDone: number = 0;
getChunkLength: (id: number) => void;
^^^^^^^^ - 'Property 'getChunkLength' has no initializer and is not definitely assigned in the constructor.'
constructor(
public name: string,
public size: string,
public chunksQuantity: number
) {}
}
UploadedFile.prototype.getChunkLength = function(id: number): void {
}
Я получаю это ужасное свойство getChunkLength не имеет инициализатора и определенно не назначается в конструкторе. ошибка.
Я попытался полностью убрать getChunkLength из class amp; interface и просто оставить его таким, каким он написан в прототипе (поскольку интерфейс должен описывать только «сторону экземпляра» класса), но затем ошибка переходит к функции в прототипе:
interface UploadFileInterface {
contentSizes: number[];
chunks: [];
chunksDone: number;
//getChunkLength: (id: number) => void;
name: string;
size: string;
chunksQuantity: number;
}
class UploadedFile implements UploadFileInterface {
contentSizes: Array<number> = [];
chunks: [] = [];
chunksDone: number = 0;
//getChunkLength: (id: number) => void;
constructor(
public name: string,
public size: string,
public chunksQuantity: number
) {}
}
UploadedFile.prototype.getChunkLength = function(id: number): void {
}
Мне кажется странным, что я не могу найти больше тем об этом сценарии, как будто это что-то очевидное или прямо объясненное в руководстве, но, похоже, я не могу его найти. Вы просто не должны добавлять вещи непосредственно в прототип в TS? Я даже пытался использовать Object.setPrototypeOf() в конструкторе, чтобы посмотреть, примет ли он его, но безуспешно.
Что я делаю не так? Должен ли я использовать ТОЛЬКО классы в TS и помещать методы непосредственно в класс? Если это так, то как фабричные функции вписываются в TS? Может кто-нибудь показать мне различные методы обхода этих ситуаций?
Ответ №1:
Вы просто не должны добавлять вещи непосредственно в прототип в TS?
Typescript ожидает, что вы будете использовать синтаксис класса для определения своих классов. Этот синтаксис может явно не указывать прототип, но функции, тем не менее, добавляются к прототипу.
Итак, в следующем примере к прототипу будет добавлена функция getChunkLength:
class UploadedFile implements UploadFileInterface {
contentSizes: Array<number> = [];
chunks: [] = [];
chunksDone: number = 0;
constructor(
public name: string,
public size: string,
public chunksQuantity: number
) {}
getChunkLength(id: string): void {
}
}
Если у вас необычный случай, когда вам нужно явно изменить прототип, тогда typescript не сможет определить, что вы делаете, и вам нужно будет утверждать, что свойство действительно определено. Это делается с помощью !
:
class UploadedFile implements UploadFileInterface {
contentSizes: Array<number> = [];
chunks: [] = [];
chunksDone: number = 0;
getChunkLength!: (id: number) => void;
// ... constructor omitted
}
UploadedFile.prototype.getChunkLength = function(id: number): void {
}
как фабричные функции вписываются в TS?
Вы можете сделать это со статической функцией в классе:
class Example () {
public static createInstance() {
return new Example();
}
private constructor() {}
}
// used like:
const example1 = Example.createInstance();
Или, если вам не нужно сохранять конструктор закрытым, вы можете просто использовать factory в качестве вспомогательной функции вне класса:
const createInstance = () => new Example();
class Example() {}