cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.06k stars 397 forks source link

Typescript definitions for JSON DSL. #361

Closed zerkalica closed 5 years ago

zerkalica commented 7 years ago

Do you think about typesafe styles builder, like typestyle ?

kof commented 7 years ago

Thats super nice! I would love such types annotations for typescript as well as for flow. But I don't have resources for it. I can keep the issue in case some will see it and wants to implement.

cvle commented 7 years ago

I opened an issue specifically for typescript type definitions that I'm already working on: https://github.com/cssinjs/jss/issues/362

cvle commented 7 years ago

To clarify my previous comment. The typescript definitions I'm working on will focus on the API and not the full JSON DSL.

kof commented 7 years ago

Also, if we have type definitions we don't need a css linter, right? cc @ai

ai commented 7 years ago

Nope. Linters is not only about right value for right property. There are many other rules. For example, that all proprerties are supported by all browsers. All that this two colors are too similar and user will not see a difference. Or warning about slow CSS properties (Facebook has custom rule for it).

kof commented 7 years ago

https://github.com/typestyle/typestyle/issues/37

cvle commented 7 years ago

The JSON DSL of jss depends on what plugins are used. Due to this dynamic nature, I don't think we can provide exact type definitions.

For example this is only valid when jss is used with the jss-camel-case plugin:

{
  fontSize: "10px"
}

And this is only valid when jss is used with the jss-default-unit plugin:

{
  "font-size": 10, 
}

The list goes on and on.

I'm still thinking about whether we could provide typescript definitions that includes all possible variations, but then they would be very permissive and of little help except maybe for autocompletion if at all. Moreover, who can say how all possible variations looks like?

Or maybe we provide type definition presets?

You see this is all quiet complicated.

First step is to have robust type definitions for the API and its plugins, which I'm working on.

cvle commented 7 years ago

Also, if we have type definitions we don't need a css linter, right? cc @ai

typescript only ensures that you are using a valid type, and not if you are using a valid value. So linters are necessary.

typestyle has a static JSON DSL as they don't support plugins. This makes it a lot easier for them to have a typesafe JSON DSL.

kof commented 7 years ago

So can we select type defs, depending on what plugins are used?

kof commented 7 years ago

Optionally, typings can be done for the default preset.

cvle commented 7 years ago

We could probably do something like this:

jss.createStyleSheet<TDefaultPreset>(styles);

And when a user needs different plugins, they need to define their own type:

jss.createStyleSheet<TCustomType>(styles);

And without type checks:

jss.createStyleSheet(styles);
zerkalica commented 7 years ago

Or generate type defs from multiple plugins.

CustomType often is combination of some plugins.

// @flow

type Base = {
  fontSize: string;
}

type UnitInPixels = {
  fontSize: number;
}

type NoCamelCaseBase = {
  'font-size': string;
}
type NoCamelCaseUnitInPixels = {
  'font-size': string;
}

generate(['jss-camel-case', 'jss-unit-in-pixels'])

outputs:

type UnitInPixels = {
  fontSize: number;
}
cvle commented 7 years ago

We probably can find a way to provide "building blocks" to help users combine their own "CustomType" easily.

cvle commented 7 years ago

@zerkalica An automated type generator would be the holy grail, but let's get there in smaller steps :-)

zerkalica commented 7 years ago

Smaller step is type definition for common set of plugins.

devdoomari commented 7 years ago

plugin-issues can be solved by 'merging' types:

https://www.typescriptlang.org/docs/handbook/declaration-merging.html

here's one example: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-css-modules/index.d.ts#L32

kof commented 7 years ago

Turns out there is already a good project https://github.com/typestyle/typestyle/

Now we just need to make it work with jss.

devdoomari commented 7 years ago

@kof typestyle/typestyle#37 I guess that didn't work out :(

how about we can 'steal' some definitions from typestyle, and work from there :P

anyway, I tried going with TypeStyle, but it didn't workout as typestyle is barely usable with multiple media queries. (TypeStyle uses FreeStyle, and FreeStyle has faulty implementations regarding style-orders - e.g. order of media-queries can get mixed-up)

kof commented 7 years ago

how about we can 'steal' some definitions from typestyle, and work from there :P

sure, I can't help though as I am using flow

appsforartists commented 6 years ago

I may end up throwing together a really lazy TS definition, primarily to get autocomplete on keys of styleSheet.classes.

I need to type create and setup before it's usable, but it's essentially:

declare namespace jss {
  export interface StyleSheet<R> {
    attach(): StyleSheet<R>,
    classes: {
      [K in keyof R]: string;
    },
  }

  export function createStyleSheet<R>(rules: R, options: {}): StyleSheet<R>;
}
kof commented 6 years ago

Thats a beginning :)

appsforartists commented 6 years ago

https://github.com/DefinitelyTyped/DefinitelyTyped/pull/21851

appsforartists commented 6 years ago

You could probably get a lot of bang:buck if you relied on @types/react's CSSProperties. If you're using the camel-case and default-unit plugins, you can check for a property in CSSProperties and use its type if one exists; falling back to [string]: any if it isn't found (or if those plugins aren't used).

kof commented 5 years ago

closing in favour of https://github.com/cssinjs/jss/issues/776