我希望得到一些关于是否/如何利用TypeScript来强烈输入类似这样的函数的建议:
function createDeserializer(typeDeserializers) {
return (data) => {
const deserializer = typeDeserializers[data.__type];
return deserializer(data);
}
}
我希望能够做到这样的事情:
const personDeserializer = createDeserializer({
'employee': (data) => new Employee(data),
'customer': (data) => new Customer(data)
});
const person1 = personDeserializer({ __type: 'employee', ... });
const person2 = personDeserializer({ __type: 'customer', ... });
// Here TypeScript knows that person1 is an 'Employee' instance, and person2 is a 'Customer' instance.
我想我需要在typeDeserializers
属性上进行某种键映射,并以某种方式将其映射到返回值,但我有点迷失。
答案 0 :(得分:3)
你去吧
class Employee {
constructor(data: any) {
Object.assign(this, data);
}
position: string;
}
class Customer {
constructor(data: any) {
Object.assign(this, data);
}
clv: number;
}
type DeserializerTypes = { [n in string]: (data: {}) => {} };
function createDeserializer<DS extends DeserializerTypes>(typeDeserializers: DS) {
return <T extends keyof DS>(data: { __type: T }): ReturnType<DS[T]> => {
const deserializer = typeDeserializers[data.__type];
return deserializer(data) as ReturnType<DS[T]>;
}
}
const personDeserializer = createDeserializer({
'employee': (data) => new Employee(data),
'customer': (data) => new Customer(data)
});
const person1 = personDeserializer({ __type: 'employee' }); // inferred as Employee
const person2 = personDeserializer({ __type: 'customer' }); // inferred as Customer
console.log(person1.position);
console.log(1000 + person2.clv);
但如果在反序列化器参数中允许属性,但仍希望TypeScript推断出确切的类型,那会有点棘手:
function createDeserializer<DS extends DeserializerTypes>(typeDeserializers: DS) {
return <T extends keyof DS, D extends { __type: T }>(data: D): ReturnType<DS[D['__type']]> => {
const deserializer = typeDeserializers[data.__type];
return deserializer(data) as ReturnType<DS[T]>;
}
}
const personDeserializer = createDeserializer({
'employee': (data) => new Employee(data),
'customer': (data) => new Customer(data)
});
const person1 = personDeserializer({ __type: 'employee', position: 'a' });
const person2 = personDeserializer({ __type: 'customer', clv: 12 });
console.log(person1.position);
console.log(1000 + person2.clv);