Skip to content

Feature request Branded type #1749

Open
@MathieuRA

Description

@MathieuRA

Hi :)

Is there a way to support branded types?

declare const __brand: unique symbol

type Branded<TBrand extends string, TType = string> = TType & { [__brand]: TBrand }

type Foo = {
   id: Branded<'foo'>
   ...
}

The above code outputs something like that:

"Branded_Foo": {
	"allOf": [
		{
			"type": "string"
		},
		{
			"properties": {
				"undefined": {
					"type": "string",
					"enum": [
						"foo"
					],
					"nullable": false
				}
			},
			"required": [
				null
			],
			"type": "object"
		}
	]
},

I also tried replacing Branded types by doing:

type ReplaceBranded<T> = {
  [K in keyof T]: T[K] extends Branded<any> ? string : T[K]
}
ReplaceBranded<Foo>

This works fine with the IDE, but the generated specs convert all properties to string instead of replacing only Branded properties.

EDIT:
I was able to work around the issue by fixing my ReplaceBranded type:

type ReplaceBranded<T> = {
  [K in keyof T]: T[K] extends Branded<string> | undefined
    ? string | undefined
    : T[K] extends Branded<string>[]
      ? string[]
      : T[K] extends Branded<string>
        ? string
        : T[K]
}

But this type removes nullable from my null values.
E.g.

ReplaceBranded<{foo: null | string}>

The openapi spec will be: foo: string

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions