Skip to content

Commit b0ce84c

Browse files
committed
feat: allow commands to be constructed without arg if all arg fields optional
1 parent a90890d commit b0ce84c

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

.changeset/six-doors-speak.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@smithy/smithy-client": patch
3+
"@smithy/types": patch
4+
---
5+
6+
allow command constructor argument to be omitted if no required members

packages/smithy-client/src/command.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
import { Command } from "./command";
22

33
describe(Command.name, () => {
4+
it("has optional argument if the input type has no required members", async () => {
5+
type OptionalInput = {
6+
key?: string;
7+
optional?: string;
8+
};
9+
10+
type RequiredInput = {
11+
key: string | undefined;
12+
optional?: string;
13+
};
14+
15+
class WithRequiredInputCommand extends Command.classBuilder<RequiredInput, any, any, any, any>()
16+
.build() {}
17+
18+
class WithOptionalInputCommand extends Command.classBuilder<OptionalInput, any, any, any, any>()
19+
.build() {}
20+
21+
new WithRequiredInputCommand({ key: "1" });
22+
23+
new WithOptionalInputCommand(); // expect no type error.
24+
});
425
it("implements a classBuilder", async () => {
526
class MyCommand extends Command.classBuilder<any, any, any, any, any>()
627
.ep({

packages/smithy-client/src/command.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
Logger,
1212
MetadataBearer,
1313
MiddlewareStack as IMiddlewareStack,
14+
OptionalParameter,
1415
Pluggable,
1516
RequestHandler,
1617
SerdeContext,
@@ -217,14 +218,16 @@ class ClassBuilder<
217218
* @returns a Command class with the classBuilder properties.
218219
*/
219220
public build(): {
220-
new (input: I): CommandImpl<I, O, C, SI, SO>;
221+
new (...[input]: OptionalParameter<I>): CommandImpl<I, O, C, SI, SO>;
221222
getEndpointParameterInstructions(): EndpointParameterInstructions;
222223
} {
223224
// eslint-disable-next-line @typescript-eslint/no-this-alias
224225
const closure = this;
225226
let CommandRef: any;
226227

227228
return (CommandRef = class extends Command<I, O, C, SI, SO> {
229+
public readonly input: I;
230+
228231
/**
229232
* @public
230233
*/
@@ -235,8 +238,9 @@ class ClassBuilder<
235238
/**
236239
* @public
237240
*/
238-
public constructor(readonly input: I) {
241+
public constructor(...[input]: OptionalParameter<I>) {
239242
super();
243+
this.input = input ?? (({} as unknown) as I);
240244
closure._init(this);
241245
}
242246

packages/types/src/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Command } from "./command";
22
import { MiddlewareStack } from "./middleware";
33
import { MetadataBearer } from "./response";
4-
import { Exact } from "./util";
4+
import { OptionalParameter } from "./util";
55

66
/**
77
* @public
88
*
99
* A type which checks if the client configuration is optional.
1010
* If all entries of the client configuration are optional, it allows client creation without passing any config.
1111
*/
12-
export type CheckOptionalClientConfig<T> = Exact<Partial<T>, T> extends true ? [] | [T] : [T];
12+
export type CheckOptionalClientConfig<T> = OptionalParameter<T>;
1313

1414
/**
1515
* @public

packages/types/src/util.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,11 @@ export interface RetryStrategy {
181181
args: FinalizeHandlerArguments<Input>
182182
) => Promise<FinalizeHandlerOutput<Output>>;
183183
}
184+
185+
/**
186+
* @public
187+
*
188+
* Indicates the parameter may be omitted if the parameter object T
189+
* is equivalent to a Partial<T>, i.e. all properties optional.
190+
*/
191+
export type OptionalParameter<T> = Exact<Partial<T>, T> extends true ? [] | [T] : [T]

0 commit comments

Comments
 (0)