I want to make types for functions like these (simplified example):
<code>function asyncStore(initialValue) {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore(sourceStore) {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
</code>
<code>function asyncStore(initialValue) {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore(sourceStore) {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
</code>
function asyncStore(initialValue) {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore(sourceStore) {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
My types draft:
<code>/* Some deps */
interface Store<T> {
value: T
}
type AnyStore = Store<any>
function createStore<T>(initialValue: T): Store<T> {
return { value: initialValue }
}
/* Types for function */
interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
}
function asyncStore<T>(initialValue: T): AsyncStore<T> {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore<T extends AnyStore>(sourceStore: T): T & { someEnhanceMethod(): void } {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
</code>
<code>/* Some deps */
interface Store<T> {
value: T
}
type AnyStore = Store<any>
function createStore<T>(initialValue: T): Store<T> {
return { value: initialValue }
}
/* Types for function */
interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
}
function asyncStore<T>(initialValue: T): AsyncStore<T> {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore<T extends AnyStore>(sourceStore: T): T & { someEnhanceMethod(): void } {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
</code>
/* Some deps */
interface Store<T> {
value: T
}
type AnyStore = Store<any>
function createStore<T>(initialValue: T): Store<T> {
return { value: initialValue }
}
/* Types for function */
interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
}
function asyncStore<T>(initialValue: T): AsyncStore<T> {
return {
...createStore(initialValue),
get 0() {
return this
},
1: createStore('pending'),
[Symbol.iterator]: function *() {
yield this[0]
yield this[1]
}
}
}
function createSomeEnhancedStore<T extends AnyStore>(sourceStore: T): T & { someEnhanceMethod(): void } {
return {
...sourceStore,
someEnhanceMethod() { /* ... */ }
}
}
const [value, status] = createSomeEnhancedStore(asyncStore(0))
Problem:
this works:
<code>const enhancedStore = createSomeEnhancedStore(asyncStore(0))
enhancedStore.someEnhanceMethod() // types ok
enhancedStore[0].someEnhanceMethod() // types ok
</code>
<code>const enhancedStore = createSomeEnhancedStore(asyncStore(0))
enhancedStore.someEnhanceMethod() // types ok
enhancedStore[0].someEnhanceMethod() // types ok
</code>
const enhancedStore = createSomeEnhancedStore(asyncStore(0))
enhancedStore.someEnhanceMethod() // types ok
enhancedStore[0].someEnhanceMethod() // types ok
this not:
<code>const [value, status] = enhancedStore // types error
</code>
<code>const [value, status] = enhancedStore // types error
</code>
const [value, status] = enhancedStore // types error
because of AsyncStore
interface should contain Symbol.iterator
property types, but how it should be described?
<code>interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
[Symbol.iterator]: Iterator<this | Store<'pending' | 'fulfilled' | 'rejected'>>
}
</code>
<code>interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
[Symbol.iterator]: Iterator<this | Store<'pending' | 'fulfilled' | 'rejected'>>
}
</code>
interface AsyncStore<T> extends Store<T> {
0: this,
1: Store<'pending' | 'fulfilled' | 'rejected'>
[Symbol.iterator]: Iterator<this | Store<'pending' | 'fulfilled' | 'rejected'>>
}
will not work:
<code>const [value, status] = enhancedStore
</code>
<code>const [value, status] = enhancedStore
</code>
const [value, status] = enhancedStore
value
and status
are this | Store<'pending' | 'fulfilled' | 'rejected'>
but expected types are this
for value
and Store<'pending' | 'fulfilled' | 'rejected'>
for status
.
Please help me.