So I want to create a function that takes a class and creates a prototype for it. But in this prototype, every property of the class is defined (including the optional ones). So here's what I want:
class Bar {
public i?: number
//...
}
class Foo {
public a?: string;
public b?: number;
public c?: Array<string>;
public l?: boolean;
public d?: Bar;
//...
}
const prot = getPrototype<Foo>();
console.log(prot); //My expected output: { a: "", b: 0, c: [], l: false, d: {}, ... }
const prot2 = getPrototype<Bar>();
console.log(prot2); // My expected output: {i: 0, ...}
I really can't see any way of doing this. If you think there's a way, I'd love to see one. The values given to the properties are supposedly hard-coded values for each type. Something like this:
//...
//... the logic for the getPrototype function ...
//...
if(typeof property === "string"){ prototype[property] = ""; }
else if(typeof property === "number"){ prototype[property] = 0; }
//...
//...
CodePudding user response:
We can achieve this by making use of Mapped Types and Conditional Property by creating a type alias InitializeType<T>
and make use of it for defining the type of getPrototype<T>
class Bar {
public i?: number
//...
}
class Foo {
public a?: string;
public b?: number;
public c?: Array<string>;
public l?: boolean;
public d?: Bar;
//...
}
type InitializeType<T> = {} & {
[K in keyof T]-?:
string extends T[K]
? ""
: number extends T[K]
? 0
: boolean extends T[K]
? false
: Array<any> extends T[K]
? []
: object extends T[K]
? {}
: T[K]
}
declare function getPrototype<T>(): InitializeType<T>
const prot = getPrototype<Foo>();
console.log(prot); // output: { a: "", b: 0, c: [], l: false, d: {}, ... }
const prot2 = getPrototype<Bar>();
console.log(prot2); // output: {i: 0, ...}