skip to Main Content

If we define a type brand such as:

declare const nominalSymbol: unique symbol;
type Nominal<T extends string, U> = U & { [nominalSymbol]: T };

Is there a way to define a type NotNominal<U> which resolves to U if U is not a branded type.

declare const nominalSymbol: unique symbol;
type Nominal<T extends string, U> = U & { [nominalSymbol]: T };

type BrandedType = Nominal<'Address', string>;

type a = NotNominal<string> // this should be `string`
type b = NotNominal<Address> // this should be `never`

2

Answers


  1. Chosen as BEST ANSWER
    type NotNominal<U> = U extends { [nominalSymbol]: string } ? never : U
    

  2. Assert unbranded type

    To define a type NotNominal<U> that resolves U if U is not type branded, a conditional type that checks if U has the [nominalSymbol]: T property. If this is the case the type will resolve to never, otherwise it resolves to U.

    My example solution of NotNominal<U>:

    declare const nominalSymbol: unique symbol;
    
    type Nominal<T extends string, U> = U & { [nominalSymbol]: T };
    
    type NotNominal<U> = U extends { [nominalSymbol]: infer T } ? never : U;
    
    type BrandedType = Nominal<'Address', string>;
    
    type a = NotNominal<string> // this should be `string`
    type b = NotNominal<BrandedType> // this should be `never`
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search