Given
class A {
props: {
bool?: boolean,
test: string
} = {
test: 'a'
};
setProps(newProps: Partial<this['props']>) {
}
a() {
this.setProps({
bool: false
});
}
}
I get an error
Argument of type
{ bool: false; }is not assignable to parameter of typePartial<this["props"]>.(2345)
As can be viewed here: same code in typescript playground
When the A.props property is defined as {bool?: boolean, test?: string} with test optional it does work, so it looks as if the Partial<> is just completely ignored.
Is there a way to get the Partial to work in conjunction with this.
The above describes the minimal case, for context: My current situation is that I have lots of classes with props that extends from a main class that has a setProps and I would like to type that inherited setProps.
class Parent {
props: any;
setProps(newProps: Partial<this['props']>) {/*...*/}
}
class A extends Parent{
props: {
bool?: boolean,
test: string
} = /* ... */;
a() {
this.setProps({
bool: false
});
}
}
Edit #2: Maybe another approach is more suitable for you. The following code implements the class Parent as an generic one receiving the interface of the properties (here PropsA) of an extending class (here A).
class Parent<T> {
props: T;
constructor(props: T) {
this.props = props;
}
setProps(props: Partial<T>) {
Object.assign(this.props, props);
}
}
interface PropsA {
bool?: boolean;
test: string;
}
class A extends Parent<PropsA> {
constructor() {
super({ test: 'A' });
}
a() {
this.setProps({
bool: false,
// Yields error:
// nonExistingProperty: true
});
}
}
const obj = new A();
console.log(obj.props); // { test: 'a' }
obj.setProps({ test: 'foo', bool: true });
console.log(obj.props); // { test: 'foo', bool: true }
obj.setProps({ test: 'foo' });
console.log(obj.props); // { test: 'foo', bool: true }
obj.a();
console.log(obj.props); // { test: 'foo', bool: false }
// Yields error:
// obj.setProps({ test: 'foo', nonExistingProperty: true });
Instead of an interface, something like class A extends Parent<{ bool?: boolean; test: string;}> { ... would also do the job. However I think, that an interface makes more sense here.
Edit #1: I have experimented a bit with ThisType. However I am not sure about its benefit, but maybe it is worth to mention:
type Descriptor<T, P> = ThisType<T> & Partial<P>;
class A {
props: {
bool?: boolean,
test: string
} = {
test: 'a'
};
setProps<T = Descriptor<this, this['props']>>(newProps: T) {
Object.assign(this.props, newProps);
}
a() {
this.setProps({
bool: true
});
}
}
const obj = new A();
console.log(obj.props); // { test: 'a' }
obj.setProps({ test: 'foo', bool: true });
console.log(obj.props); // { test: 'foo', bool: true }
Original answer: Try Partial<A['props']>:
class A {
props: {
bool?: boolean,
test: string
} = {
test: 'a'
};
setProps(newProps: Partial<A['props']>) {
// First naive assignment
Object.assign(this.props, newProps);
}
a() {
this.setProps({
bool: false
});
}
}
I guess the error appears because of this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With