Skip to content

Parameters does not work in JS files unless a @param has been explicitly defined #61172

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
RobertAKARobin opened this issue Feb 13, 2025 · 3 comments · Fixed by #61177
Closed
Assignees
Labels
Bug A bug in TypeScript

Comments

@RobertAKARobin
Copy link

RobertAKARobin commented Feb 13, 2025

🔎 Search Terms

paramaters param

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Parameters

⏯ Playground Link

https://www.typescriptlang.org/play/?strictNullChecks=true&filetype=js#code/GYVwdgxgLglg9mABAJwKYAdUEMoAoBQAkAPQBUpiAAlAJ6aIDeAzlMjGAOYC+ipxiAW1RMmWDqgA0RMhWp1UjMCAEAjVMh59EsIUykBKRkTRQQyJAEFkyLDVw7h+gHTAYAGze5do8c4BWcOy4AAaIwfoA3Phc+PgyVLT0DAAKWDZCUOpMADyJqHDAKBjYUAB8ANoADAC6msT4EAgsgsI+CgC8YQAWqB5wwVFx5AnyjKnpqJnIOXkFRZg4FQCMtbz1jWDNDkyInQDMUUA

💻 Code

function repeat(
	/** @type {string} */ message,
	/** @type {number} */ times,
) {
	return Array(times).fill(message).join(` `);
}

/** @type {Parameters<typeof repeat>[0]} */
const message = `hello`; // Error: Type '"hello"' is not assignable to type 'never'. (ts2322)

/** @type {Parameters<typeof repeat>[1]} */
const times = 3; // Error: Type '3' is not assignable to type 'never'. (ts2322)

🙁 Actual behavior

Parameters<typeof repeat> coalesces into type never.

🙂 Expected behavior

Parameters<typeof repeat> coalesces into type [message: string, times: number].

Additional information about the issue

This error occurs if a function's arguments are defined with @type, but not if they're explicitly defined with @param. For example, this works as expected:

/**
 * @param {string} message
 * @param {number} times
 */
function repeat(message, times) {
	return Array(times).fill(message).join(` `);
}

/** @type {Parameters<typeof repeat>[0]} */
export const myMessage = `hello`; // No error

/** @type {Parameters<typeof repeat>[1]} */
export const myTimes = 3; // No error

However, it is unreasonable to always require that @params be explicitly written for every function, e.g. when writing a callback that already has a defined shape.

This utility type serves as a workaround:

export type Params<Target extends (...args: any) => any> =
	Target extends (arg0: infer Arg0, arg1: infer Arg1, arg2: infer Arg2) => any  // Can add more args if we need them
	? [Arg0, Arg1, Arg2]
	: never;
function repeat(
	/** @type {string} */message,
	/** @type {number} */times,
) {
	return Array(times).fill(message).join(` `);
}

/** @type {Params<typeof repeat>[0]} */
export const myMessage = `hello`; // No error

/** @type {Params<typeof repeat>[1]} */
export const myTimes = 3; // No error
@ilogico
Copy link

ilogico commented Feb 13, 2025

there is no error

@MartinJohns
Copy link
Contributor

there is no error

There is, when you enable strictNullChecks.

@RobertAKARobin
Copy link
Author

Oops, I didn't realize I could do JS in the TS Playground. Updating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants