Closed zerkalica closed 5 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.
I opened an issue specifically for typescript type definitions that I'm already working on: https://github.com/cssinjs/jss/issues/362
To clarify my previous comment. The typescript definitions I'm working on will focus on the API and not the full JSON DSL.
Also, if we have type definitions we don't need a css linter, right? cc @ai
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).
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.
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.
So can we select type defs, depending on what plugins are used?
Optionally, typings can be done for the default preset.
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);
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;
}
We probably can find a way to provide "building blocks" to help users combine their own "CustomType" easily.
@zerkalica An automated type generator would be the holy grail, but let's get there in smaller steps :-)
Smaller step is type definition for common set of plugins.
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
Turns out there is already a good project https://github.com/typestyle/typestyle/
Now we just need to make it work with jss.
@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)
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
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>;
}
Thats a beginning :)
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).
closing in favour of https://github.com/cssinjs/jss/issues/776
Do you think about typesafe styles builder, like typestyle ?