core icon indicating copy to clipboard operation
core copied to clipboard

types(runtime-core): Allow InjectionKey to be used as a valid PropertyKey

Open pikax opened this issue 3 years ago • 4 comments

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

playground

pikax avatar Dec 10 '21 10:12 pikax