As it is possible to set CSS variables using VueJS v-bind:style binding, I am trying to create a union type where the object passed to v-bind:style retains the typings for CssStyleDelcaration and yet is relaxed enough to accept an arbitrary property name:
type Dictionary<T> = { [key: string]: T };
type Nullable<T> = T | null;
type CssStyleObject =
  Partial<CSSStyleDeclaration> |
  Dictionary<Nullable<string>>;
An example of the implementation is as such (see live code on TypeScript playground):
<!-- Template -->
<div v-bind:style="myStyle"></div>
// Component code
@Component
export default class MyComponent extends Vue {
  public get myStyle(): CssStyleObject {
    const style: CssStyleObject = { };
    style.backgroundColor = 'red';
    style['--my-custom-css-property'] = '16px';
  }
}
However, I get a type error when I have noImplicitAny flag enabled (a flag that I cannot be turned off because of a project-wide configuration), because TypeScript then complains about:
Element implicitly has an 'any' type because type 'CssStyleObject' has no index signature.
I've seen a proposed solution here: How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled?, but I would love to avoid simply casting to any, if there is another viable solution possible.
The funny thing is, the error message goes away once I use a custom property name when assigning to the style variable:
const style: CssStyleObject = {
    '--foobar': '50%'
};
style.backgroundColor = 'red';
style['--my-custom-css-property'] = '16px';
See the code above on TypeScript Playground.
I suspect that is because the type for style is then somehow modified to be simply Dictionary<string> instead of the union type, so no further errors will be thrown.
Update and solution
So, it turns out that I inherently confused intersection and union types in TypeScript. In this case, the CssStyleObject is an intersection of Partial<CSSStyleDeclaration> and Dictionary<Nullable<string>>, so this should suffice:
type Dictionary<T> = { [key: string]: T };
type Nullable<T> = T | null;
// Use `&` for creating an intersection type!
type CssStyleObject =
  Partial<CSSStyleDeclaration> &
  Dictionary<Nullable<string>>;