unsplash / intlc

Compile ICU messages into code. Supports TypeScript and JSX. No runtime.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Newtypes support

samhh opened this issue · comments

Possible syntax that wouldn't diverge too much from ICU:

{input, newtype, NewtypeName, string}

I don't know how this could be implemented in languages that support newtypes natively. Likewise it's unclear what to do in languages that don't support newtypes - just drop the wrapper?

In TypeScript via newtype-ts however this'd be achievable on account of subtyping:

type X = Newtype<{ readonly X: unique symbol }, Y>

As long as X and Y on the right side are the same then two different newtypes are assignable.

The output would be roughly:

import { Newtype } from 'newtype-ts'

export const f: (x: { input: Newtype<{ readonly NewtypeName: unique symbol }, string> }) => string = x => `${x.input}`

Given subtyping we could even define Newtype ourselves instead of importing it.

We could also extract the newtypes to the top level for better type signatures, but only if there aren't conflicts between messages (e.g. two newtypes with the same name but different inner types).

We know the runtime representation of newtypes is currently identical to the inner value so interpolating simply as above is okay (or otherwise running whatever's necessary for the inner type), however we probably shouldn't rely upon this.


We may also consider storing newtype information in a sibling property. By doing so the message can be condensed not to include the type. Downsides of this are indirection and potentially less clear interpolations for translators.

#105 and #106 are somewhat related, though this is theoretically quite a bit simpler.