Skip to content

Cannot extract base type from branded intersection #62985

@shkumbinhasani

Description

@shkumbinhasani

Problem

I use a branded intersection to mark thrown error types and want to strip the brand to recover the base type.

Repro

const errorSymbol: unique symbol = Symbol();
type Throws<E extends Error> = { [errorSymbol]?: E };

type StripThrows<T> = T extends infer R & Throws<any> ? R : T;

type Result = StripThrows<string & Throws<Error>>;

Expected

Result is string.

Actual

Result is string & Throws<Error>.

Use case

This is for a tryCatch helper that returns [data, error] where error includes declared thrown types and data is the base value type. Without stripping the brand, the data side stays intersected.

Version

TypeScript 5.7.2

Question / Request

Is there a supported way to infer the non-branded part of an intersection? If not, could TypeScript provide a utility or type operator for intersection subtraction or for inferring intersection remainders?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions