core
core copied to clipboard
types(runtime-core): Allow InjectionKey to be used as a valid PropertyKey
This allows the InjectionKey to be used as a PropertyKey, useful for the OptionsAPI.
const key = Symbol() as InjectionKey<number>
defineComponent({
provide: {
// this now works
[key]: 'foo'
}
}
This also affects VTU, since the user needs to provide it's own overrides if needed:
const colorKey = Symbol() as InjectionKey<string>
// before
mount(A, { globals: { provide: { [colorKey as symbol]: ref('#999999') } }
// after : No need to cast the symbol
mount(A, { globals: { provide: { [colorKey]: ref('#999999') } }
There's a small issue that this change brings, with this change a Symbol cannot be inferred as an InjectionKey
// before worked
const key: InjectionKey<string> = Symbol(); // worked because `InjectionKey` extended `Symbol`
// after
const key = Symbol() as InjectionKey<string>; // it need to be changed to a more lenient casting
This should lay down some work to support typed injections on the defineComponent when using Options API
Ref: https://github.com/microsoft/TypeScript/issues/46956
Providing validation on provide on defineComponent is harder than expected because when do a keyof it will convert InjectionKey type into a symbol losing the types.
const colorKey = Symbol() as InjectionKey<number>
// No Error because we cannot validate the type correctly :/
mount(A, { globals: { provide: { [colorKey]: ref('#999999') } }
Here's typescript example
declare const InjectionKeySymbol: unique symbol
export type InjectionKey<T> = symbol & { [InjectionKeySymbol]: T }
declare function extractType<T>(opts: T): { [P in keyof T]: T[P] }
const key = Symbol() as InjectionKey<number>
const s = {
[key]: 11
}
const sa = s[key]
// this should error but it does not
const sr = s[Symbol()]
const t = extractType(s)
const ta = t[key]
// this should error but it does not
const tb = t[Symbol()] // string