Skip to content

Exclude is bottlenecked by depth limit #53583

Closed

Description

@ufukbakan

When excluding a type from an unlimited type , it should calculate excluded type first but it doesnt. For example:

type NonZ = Exclude<string, 'Z'>;
const myval: NonZ = 'Z'; // doesnt give any error

Because of this bug many other bugs happens like :

interface HasNotZ {
  [key: NonZ]: number
}

const MyObj : HasNotZ = {
  Z: 123 // is still valid .... Should give an error
}

Activity

  1. MartinJohns commented on Mar 30, 2023

    @MartinJohns
    Contributor

    You forgot to fill out the issue template.

    This is working as intended. Exclude<> is used to remove types from a union type. string is not a union type, so the literal type 'Z' can be removed from it. For this to work TypeScript would need to support types like "a string, but not...", which it does not. The relevant issues for this are #4196 / #29317.

  2. fatcerberus commented on Mar 30, 2023

    @fatcerberus

    Also I’m not really sure what this has to do with a depth limit?

  3. typescript-bot commented on Apr 1, 2023

    @typescript-bot
    Contributor

    This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  4. ufukbakan commented on Apr 4, 2023

    @ufukbakan
    Author

    Also I’m not really sure what this has to do with a depth limit?

    I was aware its working with union types and thought when there is unlimited types , its bottlenecked.

  5. ufukbakan commented on Apr 4, 2023

    @ufukbakan
    Author

    However i still couldnt map my type, Omit is not working too :

    type comments = {
        [key: string]: string
    }
    
    type hasSum = {
        sum: number
    }
    
    type mergedType = Omit<comments, "sum"> & hasSum;
    
    const merged: mergedType = {
        sum: 1 // type error can not assign number to string
    }
  6. fatcerberus commented on Apr 4, 2023

    @fatcerberus

    I was aware its working with union types and thought when there is unlimited types , its bottlenecked.

    No, the depth limit is about types that are defined recursively, it has nothing to do with the number of values inhabiting the type or even whether the type is finite. The reason this doesn't work is simply because primitives like string are not union types and TS has no way internally to represent types like string & NOT "foo", so Exclude/Omit can't do anything with them.

    This is effectively a duplicate of #4196 because you're what you're trying to do requires support for negated types.

  7. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions