#typescript
#typescript
Вопрос:
приведен следующий код:
class ConnectionOptions
{
host: string = "localhost";
port: number = 5672;
username: string = "guest";
password: string = "guest";
}
class ConnectorClass
{
options: ConnectionOptions = new ConnectionOptions();
SetOptions(options: ConnectionOptions)
{
console.log(options);
this.options = options;
}
}
// Adopt singleton pattern
var Connector = (function () {
var instance : ConnectorClass;
function createInstance() {
return new ConnectorClass();
}
return {
I: function () : ConnectorClass {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// TestApp
Connector.I().SetOptions({ 'host': "192.168.17.5" });
В последней строке есть следующая ошибка машинописного текста:
index.ts:50:26 - error TS2345: Argument of type '{ host: string; }' is not assignable to parameter of type 'ConnectionOptions'.
Type '{ host: string; }' is missing the following properties from type 'ConnectionOptions': port, username, password
50 Connector.I().SetOptions({ 'host': "192.168.17.5" });
Я понимаю, почему выдается ошибка: TS ожидает 4 свойства, но я хочу установить только 1 из них, разве это невозможно в Typescript?
Ответ №1:
Для вашего кода интерфейс кажется более подходящим, чем класс. При необходимости у вас есть несколько классов, реализующих интерфейс. Затем, если вы хотите, чтобы некоторые из аргументов были необязательными, вы можете использовать необязательный модификатор ( ?
):
interface ConnectionOptions {
host?: string;
port?: number;
username?: string;
password?: string;
}
const DefaultConnectionOptions: ConnectionOptions = {
host: 'localhost',
port: 5672,
username: 'guest',
password: 'guest',
}
Теперь ваш SetOptions
метод может выглядеть примерно так:
options: ConnectionOptions = DefaultConnectionOptions;
SetOptions(options: ConnectionOptions) {
console.log(options);
this.options = { ...DefaultConnectionOptions, ...options };
}
Теперь ваш вызов Connector.I().SetOptions({ 'host': "192.168.17.5" });
должен работать, потому что никакое свойство не является обязательным.
Возможно, вы хотите, чтобы все параметры подключения были обязательными, но при вызове SetOptions
они не являются обязательными. В этом случае не используйте необязательный модификатор для свойств. Измените свою SetOptions
подпись, чтобы использовать Partial<T>
вместо:
SetOptions(options: Partial<ConnectionOptions>) {
console.log(options);
this.options = { ...DefaultConnectionOptions, ...options };
}
Приведенное выше по-прежнему будет вынуждать this.options
иметь каждое отдельное свойство, но аргумент options
не обязательно должен предоставлять все свойства.
Комментарии:
1. Большое вам спасибо, все работает отлично! Может быть, вы можете объяснить, почему класс здесь не лучший вариант? Я пришел из C #, где я бы сделал это на 100% с классом.#
2. В typescript широко распространенным шаблоном является кодирование интерфейсов. Затем создайте необходимые реализации для интерфейса. Это делает код — в целом — более гибким, поскольку основное внимание уделяется не реализации (есть статьи по этому шаблону, которые могут дополнительно объяснить). Кроме того, широкое использование анонимных объектов в javascript (
{ host: 'localhost' }
) может быть легче поддержано с помощью интерфейсов (вместо необходимости делатьSetOptions(new ConnectionOptions(....))
)