skip to content

In the Design Tokens Community Group format, how is a token's type resolved without $type, and why must tools not guess it?

level: middleimportance: should knowfreq 42%

answer

  1. explicit beats inherited
  2. an alias borrows its target's type
  3. closest group with a $type
  4. no type found means invalid
  5. same-looking values, different meanings

basics

~20 s

An explicit $type wins; otherwise an alias takes its target's type, and any other token inherits the $type of its closest parent group; with none of these the token is invalid. Guessing is banned because values of different types look alike.

solid answer

~40 s

The Design Tokens Community Group format resolves a token's type in a fixed order. A `$type` on the token itself wins. If there is none and the value is a reference, the token takes the resolved type of the token it references. Otherwise it inherits the `$type` of the **closest parent group** that declares one. If none of those apply, the token is **invalid**. Tools must not guess the type by inspecting the value, because shapes overlap: a plain number could be a line height or a font weight, and a dimension and a duration are both a number with a unit. Two tools guessing differently would turn one file into two meanings. A group's name never types anything either: a group called `color` types nothing unless it carries an explicit `$type`.

code

json · 11 lines
json
{
  "motion": {
    "$type": "duration",
    "thanks-reveal": { "$value": { "value": 240, "unit": "ms" } },
    "progress-fill": { "$value": { "value": 0.6, "unit": "s" } },
    "progress-easing": {
      "$type": "cubicBezier",
      "$value": [0.2, 0, 0, 1]
    }
  }
}

go deeper

for a junior

Recall that a token without its own $type can inherit one from its group, and that without any type it is invalid.

for a middle

Explain the full order - explicit, reference target, closest typed group, else invalid - and give concrete overlapping values that make guessing unsafe.

for a senior

Show how restructuring groups can silently change inherited types and how validation in review catches it before tokens reach consuming platforms.

for a principal

Frame strict typing as the price of interoperability: a looser, guessing format is friendlier to authors but makes every tool a separate interpretation of the same file.

## Why tokens need an unambiguous type In the **Design Tokens Community Group format**, a token's **type** tells every tool how to read and use its value: a translation tool converts a `dimension` into each platform's size unit, a design editor shows a color picker for a `color`, a documentation tool renders a swatch or a type specimen. The draft says tokens always have an unambiguous type, and every token must end up with one of the types the format defines. ## The resolution order When a token omits `$type`, tools determine it like this: 1. **Explicit `$type` on the token** - highest precedence. 2. **The referenced token's type** - if the value is a reference such as `{campaign.progress.fill}`, the token has the resolved type of the token it points at. 3. **The closest parent group's `$type`** - walk up the nesting and take the first group that declares one. 4. **Otherwise invalid** - if nothing above supplies a type, the token must be treated as invalid. And separately: if a token has a declared type but its value does not match that type's syntax, the token is invalid and tools should say so, much like a compile error for a mistyped variable. | Situation | Resolved type | |---|---| | token has `$type: duration` inside a group typed `dimension` | `duration` - explicit wins | | token has no `$type`, value `{donate.action-fill}` which is a color | `color` - from the target | | token has no `$type`, parent group has none, grandparent group typed `dimension` | `dimension` - closest typed ancestor | | no `$type` anywhere, literal value | invalid | ## Why guessing from the value is forbidden The format tells tools not to attempt to infer a type from a token's value. Several reasons make that rule essential: - **Shapes overlap.** A plain number could be a `number` (a unitless line height) or a `fontWeight`. A dimension and a duration are both an object with a numeric value and a unit. A string could be a font family name or a stroke style such as `dashed`. - **Tools would disagree.** If one tool guessed that `400` was a weight and another that it was a plain number, the same file would produce different outputs in the design editor, on the web and in the native apps. Interchange only works if every reader gets the same answer. - **Errors would hide.** A token meant to be a dimension but written without a unit is an error the author should see. A guessing tool would quietly accept it as a number. ## Groups type nothing by name Groups are for organisation, and the format says tools should not use them to infer the type or purpose of tokens. So a group **named** `color` or `spacing` does not type its children. Only a group that **declares** `$type` passes it down. Two practical consequences: - Setting `$type` once on a group of related tokens - every step of a charity site's spacing ladder, every duration for the donation confirmation animation - removes repetition and keeps each child's value checked against the type. - Moving a token to a different group can change its inherited type silently. A careful team either states `$type` on tokens that could be moved, or validates the file after every restructure. ## A charity example A charity's token file has a group `motion` with `$type: duration`, holding `thanks-reveal` and `progress-fill`. Both inherit `duration`. A contributor adds `progress-easing` to the same group with a curve as its value; the file now fails validation because a curve is not a duration. The fix is an explicit `$type: cubicBezier` on that token, or a separate group. Nobody had to guess, and the error surfaced at the point it was made. ## What to take into an interview The order - explicit, reference target, closest typed group, else invalid - and the reason behind the ban on guessing: a shared file must mean one thing to every tool that reads it, on every platform.

  • In the Design Tokens Community Group format, what happens when a token's value does not match its declared type?
    The token is invalid, and tools should show an error. `$type` is a declaration of what values are permissible, much like a declared variable type in a typed language, so a unitless number in a `dimension` token is caught where it was written instead of turning into a wrong size on some platform.
  • Why can moving a token between groups in a Design Tokens Community Group file change its type?
    A token without its own `$type` inherits from the closest parent group that declares one. Move it under a group with a different `$type` and it inherits that instead, which may make it invalid or change how tools translate it. Stating `$type` on movable tokens, or validating after restructuring, avoids the surprise.

saying these in an interview costs you the question

  • A group named color makes its children color tokens.
  • Tools may infer a token's type from what its value looks like.
  • A token without $type defaults to a string type.
  • An alias must repeat its target's $type or it is invalid.
  • The farthest ancestor group's $type wins over nearer ones.