question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Template literal types for strongly typed string values

See original GitHub issue

I’m working on a library that’s essentially typescript functions that generate valid CSS. Having just discovered template literal types, I figured out that you can essentially have strongly typed CSS strings. I think this could help tighten up csstype’s property types even further for things like CSS units, colors, functions, etc.

Some examples:

export type PCT = `${ number }%`

export function pct(amount: number): PCT {
    return `${ amount }%`
}
export type NumberOrPercent = number | PCT

export type HEX = `#${ string }`
export type RGB = `rgb(${ NumberOrPercent } ${ NumberOrPercent } ${ NumberOrPercent } / ${ NumberOrPercent })`

export type Color = HEX | RGB

export function rgb(r: NumberOrPercent, g: NumberOrPercent, b: NumberOrPercent, alpha: NumberOrPercent): RGB {
    return `rgb(${ r } ${ g } ${ b } / ${ alpha })`
}

export type ColorContrastFn = `color-contrast(${ Color } vs ${ Color })`

export function colorContrast(base: Color, compare: Color): ColorContrastFn {
    return `color-contrast(${ base } vs ${ compare })`
}

With the above types, you restrict the types of strings that are allowed to be passed into other interpolated string types to form strongly typed CSS.

// These are all valid:
colorContrast('#FFF', '#000')
colorContrast('rgb(255 255 255 / 1)', '#000')
colorContrast(rgb(255, 0, 0), 'rgb(255 0 0 / 1)')
// These are type errors:
colorContrast('asdf', '12345')
colorContrast('flex-start', 'flex-end')

This means that the Properties interface could become more strict to be something like:

interface Properties {
    backgroundColor: Color
    color: Color
}

Is this something that sounds useful for these type definitions? Is it something that’s doable based on how the type definitions are even being generated?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:3
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
buschtoenscommented, Jul 16, 2021

While I agree that strongly-typing <color> is not really feasible yet, strongly-typing any <dimension> and <percentage> value should be realistically possible, as the syntax is fairly strict for them.

Dimensions

A <dimension> is a <number> with a unit attached to it, for example 45deg, 100ms, or 10px. The attached unit identifier is case insensitive. There is never a space or any other characters between a the number and the unit identifier: i.e. 1 cm is not valid.

CSS uses dimensions to specify:

Percentages

The <percentage> data type consists of a <number> followed by the percentage sign (%). Optionally, it may be preceded by a single + or - sign, although negative values are not valid for all properties. As with all CSS dimensions, there is no space between the symbol and the number.

Would you accept a pull request? Do you have any further thoughts?

0reactions
buschtoenscommented, Jul 16, 2021

Also, what’s the rationale for not exporting the DataType namespace?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Documentation - Template Literal Types - TypeScript
Template literal types build on string literal types, and have the ability to expand into many strings via unions. They have the same...
Read more >
Fun With TypeScript Template Literal Types | by Kevin B. Greene
This is a type that must only include digits. I've worked with a lot of APIs over the years where the backend will...
Read more >
How to use template literal types for a strongly-typed "get ...
Your problem is that the type {Pre: any} has a key with the literal string value "Pre" ; it is not a string...
Read more >
Template Literal Types in TypeScript - Maina Wycliffe
Template Literal Types build on this, allowing you to build new types using a template and can expand to many different string using...
Read more >
Taming Strings with Template Literal Types - SitePen
We can compose string literals together to create strongly typed templates that control a string's value. However, we do have one missing ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found