diff --git a/packages/transformers/src/validateArgs/transformProgram.ts b/packages/transformers/src/validateArgs/transformProgram.ts index 066279058a89..6b287acc978a 100644 --- a/packages/transformers/src/validateArgs/transformProgram.ts +++ b/packages/transformers/src/validateArgs/transformProgram.ts @@ -148,11 +148,12 @@ export default function transformProgram( const methodName = method?.getName(); if (!methodName) return; - const parameters = method + const parameters: ParameterInfo[] = method .getParameters() .map((p) => { return { name: p.getName(), + isRest: p.isRestParameter(), type: p.getType(), typeName: p.getTypeNode()?.getText(), }; @@ -188,9 +189,13 @@ export default function transformProgram( of withMethodAndClassName ) { const paramSpreadWithUnknown = parameters.map((p) => - `${p.name}: unknown` + `${p.isRest ? "..." : ""}${p.name}: unknown${ + p.isRest ? "[]" : "" + }` + ).join(", "); + const paramSpread = parameters.map((p) => + `${p.isRest ? "..." : ""}${p.name}` ).join(", "); - const paramSpread = parameters.map((p) => p.name).join(", "); const context: TransformContext = { sourceFile: mfile, @@ -267,6 +272,7 @@ function getTypeName(t: Type): string { interface ParameterInfo { name: string; + isRest?: boolean; type: Type; typeName: string | undefined; } diff --git a/packages/transformers/test/fixtures/testSpread.mts b/packages/transformers/test/fixtures/testSpread.mts new file mode 100644 index 000000000000..68b030f08096 --- /dev/null +++ b/packages/transformers/test/fixtures/testSpread.mts @@ -0,0 +1,58 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +import { validateArgs } from "@zwave-js/transformers"; +import assert from "node:assert"; + +class Test { + @validateArgs() + foo(...args: number[]): void { + args; + return void 0; + } + + @validateArgs() + bar(arg1: string, ...rest: boolean[]): void { + arg1; + rest; + return void 0; + } +} + +const test = new Test(); +// These should not throw +test.foo(); +test.foo(1); +test.foo(2, 2); + +test.bar("a"); +test.bar("a", true); +test.bar("a", true, false); +test.bar("a", true, false, true); + +// These should throw +assert.throws( + // @ts-expect-error + () => test.foo(true, 1), + /args is not assignable to Array/, +); +assert.throws( + // @ts-expect-error + () => test.foo(true, 1), + /args\[0\] to be a number, got true/, +); + +assert.throws( + // @ts-expect-error + () => test.foo(undefined), + /args\[0\] to be a number, got undefined/, +); + +assert.throws( + // @ts-expect-error + () => test.bar("a", 1), + /rest is not assignable to Array/, +); +assert.throws( + // @ts-expect-error + () => test.bar("a", 1), + /rest\[0\] to be a boolean, got 1/, +);