I need to create object which will contain one property with name 'state' which will have generic type and all other properties will be functions with overriden context. I'm not sure that it is possible, because of this I decided to write to here.
I have a code:
declare interface ContextModule<State> {
state: State
}
export declare interface SuperModule<State = any> {
state?: State | any,
[methodName: string]: (this: ContextModule<State>, ...args: any[]) => any
}
const lol = {
getFoo (): any {
return this.state.foo
}
} as SuperModule
In this code I don't have any errors. It executes successfully, but if I will add
declare interface ContextModule<State> {
state: State
}
export declare interface SuperModule<State = any> {
state?: State | any,
[methodName: string]: (this: ContextModule<State>, ...args: any[]) => any
}
const lol = {
getFoo (): any {
return this.state.foo
},
+ state: { // added this property
+ foo: 'string'
+ }
} as SuperModule
Then I will see output
Conversion of type '{ getFoo(this: ContextModule<any>): any; state: { foo: string; }; }' to type 'SuperModule<any>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Property 'state' is incompatible with index signature.
Type '{ foo: string; }' is not comparable to type '(this: ContextModule<any>, ...args: any[]) => any'.
Type '{ foo: string; }' provides no match for the signature '(this: ContextModule<any>, ...args: any[]): any'.ts(2352)
I understand that problem linked with that TypeScript trying to cast property state
to [methodName: string]: (this: ContextModule<State>, ...args: any[]) => any
, but why if I declared this property before declaration for dynamic properties
May be somebody saw the same problem. Hope on your help, thanks!
The only way I could get this to work cleanly is using an intersection type, but it appears that the intersection of dynamic types and types with fixed properties (of differing type to the dynamic props) can only be created using Object.assign
.
Here is my simplified example of how this might work:
interface MyType {
requiredProp1: string
}
interface MyOtherType{
[key: string]: number
}
type ISect = MyType & MyOtherType
const obj: ISect = Object.assign({ requiredProp1: "ff" }, { foo: 1 })
const rp1 = obj.requiredProp1 //string
const foo = obj.foo //number
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