Closed
Description
TypeScript Version: 3.6.3, 3.7.0-beta
Search Terms: inference, wrong, type parameter
Code
interface Instance {
test: string
}
type DataDef<Data, Props> = Data | ((this: Readonly<Props> & Instance) => Data)
export type ThisTypedComponentOptionsWithArrayProps<Data, PropNames extends string> =
object &
ComponentOptions<DataDef<Data, Record<PropNames, any>>, PropNames[]> &
ThisType<Instance & Data & Readonly<Record<PropNames, any>>>;
type DefaultData<V> = object | ((this: V) => object);
type DefaultProps = Record<string, any>;
export interface ComponentOptions<Data = DefaultData<Instance>, PropsDef = PropsDefinition<DefaultProps>> {
props?: PropsDef;
data?: Data;
watch?: Record<string, WatchHandler<any>>;
}
export type ArrayPropsDefinition<T> = (keyof T)[];
export type PropsDefinition<T> = ArrayPropsDefinition<T>;
export type WatchHandler<T> = (val: T, oldVal: T) => void;
declare function test<Data, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<Data, PropNames>): void;
declare function test(options?: never): void
test({
data () {
return {
foo: true
}
},
watch: {
testWatch (value: boolean) {
this.test // any
}
}
})
Expected behavior:
this.test
in testWatch
is of type string
.
Actual behavior:
this.test
in testWatch
is of type any
.
Looks like Instance
keys are used as PropNames
and they override actual instance type.
Note that if I do either following things, it behaves as expected:
- Remove
value
´s type annotation. - Do not annotate
this
type ofDataDef
callback. - Do not use overload for
test
function.
Related Issues:
This is quite similar issue with #33164 but different as it can reproduce on v3.6.3 which the issue is already fixed.