Subscribe on changes!

CSS Custom Properties not accepted by StyleValue type

avatar
Oct 6th 2021

Version

3.2.19

Steps to reproduce

Try to add a CSS custom property field (e.g. --something) to a variable of type StyleValue.

What is expected?

CSSProperties type should allow any fields prefixed with --.

What is actually happening?

There is a type error:

error TS2769: No overload matches this call.
  Overload 1 of 2, '(getter: ComputedGetter<StyleValue>, debugOptions?: DebuggerOptions | undefined): ComputedRef<StyleValue>', gave the following error.
    Type '{ '--menu-item-color': string; }' is not assignable to type 'StyleValue'.
      Type '{ '--menu-item-color': string; }' is missing the following properties from type 'StyleValue[]': length, pop, push, concat, and 28 more.
  Overload 2 of 2, '(options: WritableComputedOptions<StyleValue>, debugOptions?: DebuggerOptions | undefined): WritableComputedRef<StyleValue>', gave the following error.
    Argument of type '() => { '--menu-item-color': string; }' is not assignable to parameter of type 'WritableComputedOptions<StyleValue>'.
      Type '() => { '--menu-item-color': string; }' is missing the following properties from type 'WritableComputedOptions<StyleValue>': get, set
avatar
Oct 6th 2021

Please provide a runnable reproduction as required. In case of type issues, at the very least, provide the code used to get the type error.

avatar
Oct 6th 2021

Sorry, I thought it's pretty clear so I didn't want to spend half an hour creating a repo with a reproducer. Here's the code:

  setup(props) {
    const style = computed<StyleValue>(() => ({
        '--menu-item-color': props.color ?? '',
    }));
    return {style};
  }

Or simply:

const style: StyleValue = {'--something': 'value'};
avatar
Oct 6th 2021

Next time, please read and follow https://new-issue.vuejs.org/?repo=vuejs/vue#why-repro

If you don't want to spend that time, use the forum, the Discord server or StackOverflow for questions first. But feel free to come back and open an issue if it turns out to be a bug 🙂

In your case, you have the wrong type for your computed, as yourself found this doesn't work:

const style: StyleValue = {'--something': 'value'};
avatar
Oct 6th 2021

Ok. It looks like it is a more complicated issue than I originally thought. I should probably explain it more.

I recently migrated to vue-tsc and it immediately started complaining about every style attribute I used saying that it should be of type StyleValue. So I used this type for all my style variables but then TS started complaining about the ones that contain CSS custom properties.

I can even see this type used for style attribute in Vue type definitions. So I don't understand why this type doesn't allow me to set CSS custom properties there if it works at runtime.

I will try to create a simple reproducer later today.

avatar
Oct 6th 2021

A bit further up you find this:

https://github.com/vuejs/vue-next/blob/6171aecdcd5f71163c384479b225b731a10a8184/packages/runtime-dom/types/jsx.d.ts#L32-L41

Which says you can either add an index signature yourself or add individual custom properties, for better type safety.

// style.d.ts
import type { CSSProperties } from 'vue'

declare module 'vue' {
  interface CSSProperties {
    // declare individual properties for maximum type safety
    '--some-property': string
    // or provide a simple index signature:
    [k: string]: string
    // limited to custom properties:
    [k: `--${string}`]: string
  }
}

Likely something worth documenting in our still growing Typescript docs. /cc @pikax