sindresorhus / type-fest

A collection of essential TypeScript types
Creative Commons Zero v1.0 Universal
14k stars 531 forks source link

Label<Type, Token> #702

Open jamiebuilds opened 11 months ago

jamiebuilds commented 11 months ago
Effect Opaque Labeled
Preserve type name
Requires as
declare const label: unique symbol;

export type LabelContainer<Token> = {
    readonly [label]?: Token;
  //              ^ This the only difference between Label and Opaque
};

export type Label<Type, Token = unknown> = Type & LabelContainer<Token>;

Example:

type NormalString = string
type PatternString = Label<string, "PatternString">

type Options = {
  prefix: NormalString,
  pattern: PatternString,
  opaquePattern: OpaquePatternString
}

let options: Options = {
  prefix: "foo/",
  // ^? (property) prefix: string
  pattern: "{bar,baz}"
  // ^? (property) pattern: PatternString
}

// No `as PatternString` or `patternString("...")`
let pattern: PatternString = "{bar,baz}" 

TS Playground

Upvote & Fund

Fund with Polar

sindresorhus commented 11 months ago

We already have two similar types for this now Opaque and Tagged. If we add a third one, we need to make sure we clearly describe the differences.

sindresorhus commented 11 months ago

// @ethanresnick @Emiyaaaaa Thoughts?

ethanresnick commented 10 months ago

I can't say I've ever had a need for something like this in my code (that I remember), or seen use cases for this discussed much on the TS repo's issues about tagged types. It might be worth it to collect more feedback/signals of demand before adding this.