Skip to content

Type discrimination bug with string literal tuple.Β #59785

Closed as not planned
Closed as not planned

Description

πŸ”Ž Search Terms

"discriminated union", "discrimination", "literal tuple", "string literal tuple"

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAQghgZ2gXigbwLACgq6gSwBMB+ALigWACd8A7AcwG5s8oBrCEMi6up7AL7ZsoSFACCAFXAp0LPHCpU4IcgG0A5HA0BdZjjwAzfBAA2hBNzRRacALYRulGgwA0UOIUJUICS+Wc+AUYoAHpQqAAxE3MEDx8PU1MAewB3CEIoZNpTEChDZKooLQ1BfREZWGkxVEwDXEVlVShNACNdfVYfQnwfAGNgAFUAJQAZchHRqAAfHhcmMIjhiABHAFdejPzC4vay4SxRaHE4WkIYatk61kaVdRL3DXadGZanjUftPXlcbs2ByYTMavQIMELhKDLdabTIFIrvH5QQgQQxwNamYAASWAEDs3BKr3enSMMQsVhs9kcAV4bg8Xh8ficNPowUWUVJcUU0DgSTSW1SAAsILQoK1ksABcVtB4zrsNPFoGAGcLgPssBUxABhbLGehQVDwJBQABkUAAFFJKrMLlaJKdzpcAJTlLB9bKUKA4yjkbW0XX6uRYACQt2ami+rmwQb+-SGY3IGgFwGAYAQpHCEAAHvYwKYIAA6N12eXhAA85YAtFXPQL8HEEALkujMhKqGkZVAIEpCvnBEA

πŸ’» Code

type Base = {
    id?: string;
    key?: string;
}

type AType = {
    array: ['a'];
    fields?: { name?: string, address?: string}; // Fields are allowed only for 'a'
};

type BType = {
    array: ['b'];
    redirectURL: URL | string; // Required for 'b'
};

type AandBType = {
    array: ['a', 'b'] | ['b', 'a'];
    redirectURL: URL | string; // Required for 'b'
    defaultItem?: 'a' | 'b';
    fields?: { name?: string, address?: string}; // Fields are allowed when both 'a' and 'b' are present
};

type Config = Base & (AType | BType | AandBType);

const test: Config = {
	array: ['a'],
	redirectURL: 'https://example.com' //<<<--- this should throw an error.
}

πŸ™ Actual behavior

The following test variable is suggest every field regardless of the array: ['a'].

const test: Config = {
	array: ['a']
}

And it not thrown errors if i declare a non related property.

const test: Config = {
	array: ['a'],
	redirectURL: 'https://example.com', //<<<--- this should throw an error.
	defaultItem: 'a' //<<<--- this should throw an error as well.
}

πŸ™‚ Expected behavior

The following test variable should suggest the discriminated type fields by default.

const test: Config = {
	array: ['a']
}

And it not thrown errors if i declare a non related property.

const test: Config = {
	array: ['a'],
	redirectURL: 'https://example.com', //<<<--- this should throw an error.
	defaultItem: 'a' //<<<--- this should throw an error as well.
}

Additional information about the issue

No response

Activity

  1. changed the title [-]Type discrimination with array of string literal.[/-] [+]Type discrimination with string literal touple.[/+] on Aug 28, 2024
  2. changed the title [-]Type discrimination with string literal touple.[/-] [+]Type discrimination bug with string literal touple.[/+] on Aug 28, 2024
  3. RobertSandiford commented on Aug 28, 2024

    @RobertSandiford

    Config can be rewritten as type Config = (Base & AType) | (Base & BType) | (Base & AandBType) with the same result.
    I looked at this and figured that when checking compatibility the checker could look for matching union members, then apply the Excess Property Check to each matching member, ruling out any that fail, or throw an EPC error if they all fail. But it doesn't seem to.

    Changing array to a string, which TS seems to need to use it as a discriminator makes the EPC kick in. But I'm just not getting why an EPC check on a union needs a discriminator. I may be missing something, but seemed solvable to me.

  4. MartinJohns commented on Aug 28, 2024

    @MartinJohns
    Contributor

    But I'm just not getting why an EPC check on a union needs a discriminator.

    #20863

  5. jcalz commented on Aug 28, 2024

    @jcalz
  6. changed the title [-]Type discrimination bug with string literal touple.[/-] [+]Type discrimination bug with string literal tuple.[/+] on Aug 29, 2024
  7. typescript-bot commented on Sep 1, 2024

    @typescript-bot
    Contributor

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

  8. 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