csstype
csstype copied to clipboard
How to limit the StandardLonghandProperties[`propertyName`] type to valid strings?
I'd like to make sure the user will be able to provide only a valid strings to a component with this props:
interface ComponentProps {
width?: StandardLonghandProperties["width"]
}
but it allows to provide any string or number:
<Component width="foo-bar" />
I've noticed that it could work when I remove | (string & {}); from this interface:
export type Width<TLength = (string & {}) | 0> =
| Globals
| TLength <--- this might be string
| "-moz-fit-content"
| "-moz-max-content"
| "-moz-min-content"
| "-webkit-fit-content"
| "-webkit-max-content"
| "auto"
| "fit-content"
| "intrinsic"
| "max-content"
| "min-content"
| "min-intrinsic"
| (string & {}); <---
Now I'm able to pass 0 as a type param to the StandardLonghandProperties interface:
interface ComponentProps {
width?: StandardLonghandProperties<0>["width"]
}
...
<Component width="foo-bar" /> // this fails
<Component width="auto" /> // this pass
<Component width="10px" /> // this fails
As a solution for the issue with px, rem etc I suggest using Template Literal Types:
| `${number}${`px`|`em`|`rem`|`vw`|`vh`}`;
It'd have to be:
type Unit = `${number}${`ch`|`em`|`px`|`rem`|`vh`|`vw`|`%`}`;
type CSSFunction = `${string}(--${string | number})`; // like `var(--some-var)` or `calc(100% - 220px)`
type StandardLonghandPropertiesValue = Unit | CSSFunction;
at least.
Can't think of other edge cases, but this sort of typing is tough... Even CSSFunction could be spoofed wrong.