Skip to content

[5.4 regression] Conditional type changes behavior with 5.4-betaΒ #57221

Closed as not planned
@danvk

Description

@danvk

πŸ”Ž Search Terms

5.4 regression

πŸ•— Version & Regression Information

  • This changed between versions 5.3.3 and 5.4-beta

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.0-dev.20240129#code/KYDwDg9gTgLgBDAnmYcCiIZQIYGMYBKEArjMAArY4C2AzgDwAqcoZAdgCa1y1YCWbAOYA+OAF4e-IS0zBO3RgFgAUHDgB+OAWC5oHerygDBAGklGhwlWoBccZqzlc4AAwAkAbwEAzYFDgA+gDKMFQwAL42nj5+cJQ04QD00Wy+-tq84S7WGnAecADaANZwAnFU2NRwAD5wRcCIEN7omDj4RKQUFXT0GTDCALp2hsZw4Tl2DrLyrilpgSFhkXOx8ZVZOZr5xaVs5TRD5qPjqnB2HuEA3CoqHDoANlSo3sRs+HwQe-cCRUwy7M4RpYABQ5KiCWjnHJqMDYGAAC0m11O4TgADI4MCLv8nNwMFg8IQSGQ1j1GKItnBYTRaOpzqjUecqd1IS0Ce1iV0aUxROEAJQmFR8uwANwgfA4yJUiUSLCgUGguwQ3AArAA6ADMmrg2E4cHVABY1QAGAC0ACNgKEVN82EUscyEXYAOSJGzeCAQN3mqjOszUyqs7H85EyuUK-xlGCqzWasxsCDhxVRmNGs2W0JquBBeEke4cOCWnV7PwRtU2n4O2FOuCu92e71URJ+5k0pkeiAujvOsZjPnIoA

πŸ’» Code

export type ExtractRouteParams<T extends string> = string extends T
  ? Record<string, string>
  : T extends `${infer _Start}:${infer Param}/${infer Rest}`
  ? { [k in Param | keyof ExtractRouteParams<Rest>]: string }
  : T extends `${infer _Start}:${infer Param}`
  ? { [k in Param]: string }
  : {};

declare function link<T extends string>(
  args: {
    path: T;
  } & ({} extends ExtractRouteParams<T> ? { params?: {} } : { params: ExtractRouteParams<T> }),
): void;

// error in ts 5.3.3 and 5.4.0-beta
link({ path: '/:foo/:bar', params: {} });
// error in ts 5.3.3, no error in ts 5.4.0-beta
link({ path: '/:foo/:bar/', params: { foo: 'foo' } });

πŸ™ Actual behavior

The last line is only an error in TS 5.3.3, not TS 5.4-beta.

πŸ™‚ Expected behavior

I'd expect it to be an error in both (foo isn't specified).

Additional information about the issue

Putting NoInfer in the conditional type makes the expected error reappear:

- } & ({} extends ExtractRouteParams<T> ? { params?: {} } : { params: ExtractRouteParams<T> }),
+ } & ({} extends ExtractRouteParams<NoInfer<T>> ? { params?: {} } : { params: ExtractRouteParams<NoInfer<T>> }),

So perhaps this is WAI? Just wanted to flag it as a change I noticed from 5.3.3 to 5.4-beta.

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