Skip to content

Commit

Permalink
fix: inference of optional properties (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
KATT committed Mar 19, 2024
1 parent 51c82e5 commit 7b34ce7
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
40 changes: 37 additions & 3 deletions javascript/src/rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,18 +758,52 @@ describe('RetoolRPC', () => {
arguments: {},
implementation: async () => {
return 1
}
},
})

type ExpectedImplementation = (args: TransformedArguments<Arguments>, context: RetoolContext) => Promise<number>
expectTypeOf(fn).toEqualTypeOf<ExpectedImplementation>()


const result = await fn({}, context);
const result = await fn({}, context)
expect(result).toEqual(1)
expectTypeOf(result).toEqualTypeOf(1)
})

test('infers non-required properties as optional', async () => {
const fn = rpcAgent.register({
name: 'test',
arguments: {
explicitRequired: {
type: 'number',
required: true,
},
explicitOptional: {
type: 'number',
required: false,
},
implicitOptional: {
type: 'number',
},
},
implementation: async (args) => {
expectTypeOf(args.explicitRequired).toEqualTypeOf<number>()

expectTypeOf(args.explicitOptional).toEqualTypeOf<number | undefined>()
expectTypeOf(args.implicitOptional).toEqualTypeOf<number | undefined>()

return args
},
})

const result = await fn(
{
explicitRequired: 1,
},
context,
)

expectTypeOf(result.explicitOptional).toEqualTypeOf<number | undefined>()
})
})

describe('RetoolRPCVersion', () => {
Expand Down
8 changes: 5 additions & 3 deletions javascript/src/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,15 @@ export class RetoolRPC {
/**
* Registers a Retool function with the specified function definition.
*/
register<TArgs extends Arguments, TReturn>(spec: RegisterFunctionSpec<TArgs, TReturn>): RegisterFunctionSpec<TArgs, TReturn>['implementation'] {
register<TArgs extends Arguments, TReturn>(
spec: RegisterFunctionSpec<TArgs, TReturn>,
): RegisterFunctionSpec<TArgs, TReturn>['implementation'] {
this._functions[spec.name] = {
arguments: spec.arguments,
permissions: spec.permissions,
implementation: spec.implementation,
implementation: spec.implementation as RegisterFunctionSpec<any, any>['implementation'],
}
return spec.implementation;
return spec.implementation
}

/**
Expand Down
24 changes: 19 additions & 5 deletions javascript/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,17 @@ export type ArgumentType = 'string' | 'boolean' | 'number' | 'dict' | 'json'
export type Argument = {
/** The type of the argument. */
type: ArgumentType
/** Specifies whether the argument is expected to be an array. */
/**
* Specifies whether the argument is expected to be an array.
* @default false
*/
array?: boolean
/** The description of the argument. */
description?: string
/** Specifies whether the argument is required. */
/**
* Specifies whether the argument is required.
* @default false
*/
required?: boolean
}

Expand Down Expand Up @@ -68,10 +74,18 @@ export type TransformedArgument<TArg extends Argument> = TArg['array'] extends t
? Array<ArgumentTypeMap<TArg>>
: ArgumentTypeMap<TArg>

type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
type GetOptionalArgs<TArgs extends Arguments> = {
[TArg in keyof TArgs]: TArgs[TArg]['required'] extends true ? never : TArg
}[keyof TArgs]

/** Represents a map of argument names to argument types. */
export type TransformedArguments<TArgs extends Arguments> = {
[TArg in keyof TArgs]: TransformedArgument<TArgs[TArg]>
}
export type TransformedArguments<TArgs extends Arguments> = PartialBy<
{
[TArg in keyof TArgs]: TransformedArgument<TArgs[TArg]>
},
GetOptionalArgs<TArgs>
>

/** Represents the specification for registering a Retool function. */
export type RegisterFunctionSpec<TArgs extends Arguments, TReturn> = {
Expand Down
4 changes: 2 additions & 2 deletions javascript/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
/* Additional Checks */
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"allowSyntheticDefaultImports": true
},
"ts-node": {
// these options are overrides used only by ts-node
// same as the --compilerOptions flag and the TS_NODE_COMPILER_OPTIONS environment variable
"compilerOptions": {
"module": "commonjs"
}
},
}
}

0 comments on commit 7b34ce7

Please sign in to comment.