I have a javascript class that I want to rewrite to TS:
class A {
constructor({foo = 'foo', bar = 123, baz = true} = {}) {
this.foo = foo
this.bar = bar
this.baz = baz
}
}
What that I currently wrote on TS:
interface AProps {
foo: string,
bar: number,
baz: boolean,
}
class A {
foo: string
bar: number
baz: boolean
constructor({foo = 'foo', bar = 123, baz = true}: Partial<AProps> = {}) {
this.foo = foo
this.bar = bar
this.baz = baz
}
}
As you can see, typescript has 3 times more code, how to do this more compact? As I know, almost any code duplication is anti-pattern so there must be the way to tell typescript that I want all fields in class from that interface.
You don't need to specify AProps interface to hint type of the constructor, it will be inferred correctly.
class A {
foo: string
bar: number
baz: boolean
constructor({foo = 'foo', bar = 123, baz = true} = {}) {
this.foo = foo
this.bar = bar
this.baz = baz
}
}
Constructor has type:
constructor A({ foo, bar, baz }?: {
foo?: string | undefined;
bar?: number | undefined;
baz?: boolean | undefined;
}): A
const a = new A({x: 1});
fails to compile with a message
Argument of type '{ x: number; }' is not assignable to parameter of type '{ foo?: string | undefined; bar?: number | undefined; baz?: boolean | undefined; }'. Object literal may only specify known properties, and 'x' does not exist in type '{ foo?: string | undefined; bar?: number | undefined; baz?: boolean | undefined; }'.(2345)
With original code
constructor has type:
constructor A({ foo, bar, baz }?: Partial<AProps>): A
const a = new A({x: 1});
fails to compile with a message
Argument of type '{ x: number; }' is not assignable to parameter of type 'Partial<AProps>'. Object literal may only specify known properties, and 'x' does not exist in type 'Partial<AProps>'.(2345)