frenic / csstype

Strict TypeScript and Flow types for style based on MDN data
MIT License
1.74k stars 74 forks source link

Type safety support for properties which has (string & {}) definition #149

Open barinbritva opened 2 years ago

barinbritva commented 2 years ago

Hi there,

I use a library typestyle which depends on csstype. And I have a next case:

import {style} from 'typestyle';

export const styles = {
  header: style({
    // There are IDE hints, but I'm still able to put any value
    display: 'flexxxxx',
  })
};

It happens because the definition of display looks like:

  export type Display =
    | Globals
    | DataType.DisplayOutside
    | DataType.DisplayInside
    | DataType.DisplayInternal
    | DataType.DisplayLegacy
    | "contents"
    | "list-item"
    | "none"
    | (string & {});

I understand the definition relies on web specifications and that's absolutely correct. But it doesn't make sense from a type safety perspective.

Is it possible to solve the issue? Maybe csstype could do two kind of builds - default and type safe?

frenic commented 2 years ago

Hopefully this could be solved with template literal types in the future. But it requires some additional work before we can use template literal types.

barinbritva commented 2 years ago

@frenic thank for the answer!

For sure literal types would provide extremely cool experience! Do you have a plan to use them in the project any time soon?

Speaking of (string & {}) definition - which use cases will be broken without it? Some properties like display has only white list of properties and they don't need common string.

frenic commented 2 years ago

As soon as I have time to fix it. Soon I hope.

That's not true. The display property accepts a two-value syntax even though it's rarely used. That's why string & {} is generated.

barinbritva commented 2 years ago

Oh, two-value syntax, now I see... Could string & {} be potentially replaced by full list of combinations? Or there is no necessary data to do it?

frenic commented 2 years ago

It's pretty intense to generate a union for every possible combination for every property of this kind. That's why literal template types will come in handy.