typescript - 为静态方法包含定义类型参数约束
问题描述
如果是序列化程序,我可以定义类型具有特定静态成员/“静态”实现接口的类型参数约束吗?
意义:
function getStuff<T>(...) -> T {
T.buildFormJson(getStuffJson(...))
}
哪里buildFromJson
是function(input: Object): T
我可以为 T 定义一个约束,只接受定义了这个静态成员的类型吗?
解决方案
基于:https ://github.com/microsoft/TypeScript/issues/13462#issuecomment-275860898
interface JsonDeserializable<T> {
fromJson(obj: Object): T;
}
interface JsonSerializable {
toJson(): Object;
}
用法:
import * as assert from "assert";
class Point2D {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
toJson(): Object {
return this;
}
static fromJson(obj: Object): Point3D {
return new Point3D(obj['x'], obj['y'], obj['z']);
}
}
class Point3D {
x: number;
y: number;
z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
toJson(): Object {
return this;
}
static fromJson(obj: Object): Point3D {
return new Point3D(obj['x'], obj['y'], obj['z']);
}
}
class Baz {
foo: Point2D;
bar: Point3D;
constructor(foo: Point2D, bar: Point3D) {
this.foo = foo;
this.bar = bar;
}
toJson(): Object {
return {
foo: this.foo.toJson(),
bar: this.bar.toJson()
}
}
static fromJson(obj: Object): Baz {
return new Baz(Point2D.fromJson(obj['foo']), Point3D.fromJson(obj['bar']));
}
}
var DATA: Object = {};
function getJson(): Object {
return DATA;
}
function saveJson(o: Object) {
DATA = o;
}
// Only accepts T that is serializable
function save<T extends JsonSerializable>(o: T) {
const json = o.toJson();
saveJson(json);
}
// Only accepts T that is deserializable
function load<InstanceType>(cls: JsonDeserializable<InstanceType>): InstanceType {
const data = getJson();
return cls.fromJson(data);
}
// Only accepts T that is both serializable and deserializable
function testSerde<T extends JsonSerializable>(cls: JsonDeserializable<T>, obj: Object) {
const instance = cls.fromJson(obj);
const json = instance.toJson();
assert.deepEqual(json, obj);
}
const baz = new Baz(new Point2D(1,2), new Point3D(1,2,3));
save(baz);
console.log(load(Baz)); // Baz object
testSerde(Baz, { foo: { x: 1, y: 2 }, bar: {x: 1, y: 2, z: 3}});
推荐阅读
- sql - 从 SQL 结果集中获取两行之间的日期差异
- amazon-web-services - 旧 SSL 证书优先于新证书
- javascript - 在滚动底部生成 div
- vb.net - 随机图像卡在一张图像上
- c# - HttpClient 未使用客户端证书进行双向 TLS 身份验证
- spring-boot-admin - 如何修复“⚠️配置 INFO 失败。” 尝试在 Spring Boot Admin 中设置 ROOT 记录器级别时?
- c# - 使用 Newtonsoft 将复杂的 JSON 转换为通用列表
- c - 获取 MacOS 进程 pid
- android - 如何在课堂上使用 Shared Preferences 来设置所有活动?
- ios - 从弹出窗口呈现自定义弹出窗口然后关闭第一个弹出窗口会导致闪烁