Skip to content

rest parameter ts2556 and ts2345 #57170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
liukonghe opened this issue Jan 25, 2024 · 3 comments
Closed

rest parameter ts2556 and ts2345 #57170

liukonghe opened this issue Jan 25, 2024 · 3 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@liukonghe
Copy link

πŸ”Ž Search Terms

ts2556 ts2345

πŸ•— Version & Regression Information

version: 5.3.3

⏯ Playground Link

No response

πŸ’» Code

const BoxGeometry = (_width: number, _height: number) => undefined;
const SphereGeometry = (_radius: number, _height: number, _openEnded?: boolean) => undefined;

export const Geometry = {
  Box: BoxGeometry,
  Sphere: SphereGeometry,
};

type GeometryType = keyof typeof Geometry;

export type GetArgument<T extends GeometryType> = Parameters<(typeof Geometry)[T]>;

export function load<T extends GeometryType>(type: T, args: GetArgument<T>) {
  const geometry = Geometry[type](...args);
}

πŸ™ Actual behavior

image

πŸ™‚ Expected behavior

...args should not report an error

Additional information about the issue

No response

@Andarist
Copy link
Contributor

Likely this particular error would get fixed with #50034 but it wouldn't fix the correlation problem. To fix the latter (and have it working today) you can use the pattern introduced by TS 4.6 (here):

const BoxGeometry = (_width: number, _height: number) => undefined;
const SphereGeometry = (
  _radius: number,
  _height: number,
  _openEnded?: boolean,
) => undefined;

type TypeMap = {
  Box: Parameters<typeof BoxGeometry>;
  Sphere: Parameters<typeof SphereGeometry>;
};

type GeometryType<P extends keyof TypeMap = keyof TypeMap> = {
  [K in P]: (...args: TypeMap[K]) => undefined;
};

export const Geometry: GeometryType = {
  Box: BoxGeometry,
  Sphere: SphereGeometry,
};

export function load<K extends keyof TypeMap>(type: K, args: TypeMap[K]) {
  const geometry = Geometry[type](...args);
}

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Jan 29, 2024
@RyanCavanaugh
Copy link
Member

The example + links in #57170 (comment) is the best we can do without potentially combinatorial explosion

@Andarist
Copy link
Contributor

Andarist commented Feb 27, 2024

So it seems that the change from #50034 (merged as part of #57122 ) didn't fix the "A spread argument must either have a tuple type or be passed to a rest parameter.(2556)" problem here. I think that part should still work, since TS is able to verify that ...args are spreadable in other circumstances (TS playground):

const BoxGeometry = (_width: number, _height: number) => undefined;
const SphereGeometry = (
  _radius: number,
  _height: number,
  _openEnded?: boolean,
) => undefined;

export const Geometry = {
  Box: BoxGeometry,
  Sphere: SphereGeometry,
};

type GeometryType = keyof typeof Geometry;

export type GetArgument<T extends GeometryType> = Parameters<
  (typeof Geometry)[T]
>;

function acceptAtLeastOne(a: any, ...args: any[]) {}

export function load<T extends GeometryType>(type: T, args: GetArgument<T>) {
  const geometry = Geometry[type](...args); // error (but a wrong one)
  acceptAtLeastOne(...args); // error

  const extendedArgs1 = [{}, ...args] as const; // ok
  const extendedArgs2: readonly [any, ...any[]] = [{}, ...args] as const; // ok
}

EDIT:// This might be a different long-standing issue~ since this comes from getArgumentArityError. So it's not about assignability per-se

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants