Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Support for literal template strings? #14221

Discussion options

Now that we have literal types in scala, we can define a type as a set of possible literal values as union of literal values

// Scala 3
 type Prime = 2 | 3 | 5 | 7
 var prime: Prime = 7 // valid
 prime = 2 // valid
 prime = 6 // invalid

However, there may be case where we want to define a pattern-based set of literal values like a set of gray tones for a UI theme :
{ "gray-50", "gray-75", "gray-100", "gray-200" }

One may wonder if there is a way to express this literal set using a string pattern like interpolation or regex, indeed, typescript already implemented a way for expressing this string patterns as Template Literal Types

// TypeScript
type ranges = '50' | '75' | '100' | '200'
type grays = `gray-${ranges}` 
/** Generated type
 * type grays = "gray-50" | "gray-75" | "gray-100" | "gray-200"
 */

Some other examples of use cases will range from
Define names of events or error (useful in scala.js environments where JavaScript events names are passed as string) like

// JavaScript
person.on("age-changed", newAge => { 
 if (newAge < 0) {
 console.warn("warning! negative age");
 }
})

where you may have an event name for each person property like name-changed | age-changed | friends-changed then the function parameter can be typed as a literal set defined as regex or interpolation like ${prop}-changed

Regex logic may be useful for defining the set of strings composed of alphanumeric characters of length 2 by using [\w+]{2} however this is way more complex than interpolation.

From the Programming is Scala book by @odersky section 5.3

In Scala, string interpolation is implemented by rewriting code at compile time. The compiler will treat any expression consisting of an identifier followed immediately by the open double quote of a string literal as a string interpolator expression. The s, f, and raw string interpolators are implemented via this general mechanism. Libraries and users can define other string interpolators for other purposes.

Could a custom type interpolator be defined as mechanism for template literal types?

type Grays = s"gray-${50 | 75 | 100 | 200}."
// type Grays = "gray-50" | "gray-75" | "gray-100" | "gray-200"
You must be logged in to vote

you can do this with a match type:

import scala.compiletime.ops.string.+
type OfString[S <: String] = S
type Spread[S <: String, T <: NonEmptyTuple] = T match
 case OfString[t] *: EmptyTuple => S + t
 case OfString[t] *: ts => (S + t) | Spread[S, ts]
type Grays = Spread["gray-", ("50", "75", "100", "200")]
val `gray-50`: Grays = "gray-50"

then you can use this as a template to support more than one splice

Replies: 1 comment

Comment options

you can do this with a match type:

import scala.compiletime.ops.string.+
type OfString[S <: String] = S
type Spread[S <: String, T <: NonEmptyTuple] = T match
 case OfString[t] *: EmptyTuple => S + t
 case OfString[t] *: ts => (S + t) | Spread[S, ts]
type Grays = Spread["gray-", ("50", "75", "100", "200")]
val `gray-50`: Grays = "gray-50"

then you can use this as a template to support more than one splice

You must be logged in to vote
0 replies
Answer selected by 3xau1o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /