typescript - 在 Typescript 中定义类的更短方法?
问题描述
一个标准的类声明如下所示:
class Foo {
a: string;
b: string;
constructor({ a, b }: { a: string, b: string }) {
this.a = a;
this.b = b;
}
}
这需要你复制一个变量 4 次——一个类型两次!可能看起来没什么大不了的,但它为一个非常简单的任务创建了不必要的样板,并且对字符串文字有问题,因为它要求您在多个地方都有硬编码的字符串。
我发现唯一更简单的方法是使用接口:
interface Foo {
a: string;
b: string;
}
const getFoo = ({ a, b }: Foo): Foo => ({ a, b });
但是现在需要同时导出 getter 和接口,这有点倒退。
有没有我想念的更简单的方法?
我很想看到像 Dart 的初始化器这样的东西:
class Foo {
String a;
String b;
Foo({ this.a, this.b });
}
更新:
受到其中一个答案的启发,采取了更实用的方法:
interface Test {
a: string;
b: string;
}
export function get<T>(params:T):T {
return params;
}
get<Test>({ a: 'hello', b: 'world' });
不幸的是,它缺少默认值。
解决方案
避免这种样板的一种方法是将其重构为您自己的库函数(这可能需要使用类型断言来说服编译器不要抱怨)
function ifaceToCtor<T extends object>(): new (param: T) => T {
return class {
constructor(arg: any) {
Object.assign(this, arg);
}
} as any;
}
然后,您无需创建普通类,而是定义一个接口并使用以下命令创建其构造函数ifaceToCtor
:
interface Foo { a: string, b: string };
const Foo = ifaceToCtor<Foo>(); // short!
您可以验证它是否有效:
const foo = new Foo({ a: "eh", b: "bee" });
console.log(foo.a); // eh
console.log(foo.b); // bee
这类似于您的“getter”想法,但这是一个真正的类(如果重要的话),用于Object.assign()
避免属性名称的重复并允许将其隐藏到您不需要查看的某个库中。
同样,您可以使用ifaceToCtor
扩展 nonce 超类来添加不属于构造函数参数的方法或其他道具:
class Bar extends ifaceToCtor<{ c: string, d: number }>() {
method() {
return this.c.toUpperCase() + " " + this.d.toFixed(2);
}
}
const bar = new Bar({ c: "hello", d: 123.456 });
console.log(bar.method()); // HELLO 123.46
而且这个版本的优点是您要导出的是标准外观class
,其中命名的接口和构造函数Bar
被带入您的范围,而不需要第一个示例中的interface
-and- const
。
好的,希望有帮助;祝你好运!
推荐阅读
- vb.net - 为什么我的 Visual Basic 程序会退出?它在启动后一分钟内停止执行
- html - 使用跨越几张卡片的图表作为背景
- azure-devops - 无法在 Azure Pipelines 中有条件地下载安全文件
- php - 在特定 WooCommerce 电子邮件模板上将动态值插入文本字符串
- rust - 在 Rust 中使用引用和使用拥有值之间有区别吗?
- discord.py - Bot在while循环中发送消息
- azure-powershell - 如何使用 PowerShell 5.1 安装 AzureRM 和 AZ 模块?
- database - 如何允许某人运行我的 Oracle 函数/程序但无法查看其源代码
- php - 图片未加载 Wordpress 网站
- java - 如何在java中映射时区国家及其城市