Skip to content

[Bug] Changes in type inference of activity return type in SDK 1.12.2Β #1796

@rd-akind

Description

@rd-akind

What are you really trying to do?

Call an activity from a workflow, through proxyActivities, and use TypeScript's type inference to determine the activity return type.

Describe the bug

When using TypeScript SDK 1.12.1, calling an activity and storing its return value in a variable always successfully compiles.

In TypeScript SDK 1.12.2 and above, some instances of code that previously successfully compiled, now emits the error:

error TS7022: '...' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

Minimal Reproduction

An example repo with nonsensical code but minimal TypeScript configuration can be found here: https://github.com/akindgroup/temporal-repro-1657

One of the circumstances where TypeScript is not able to infer the type correctly when upgrading past TypeScript SDK 1.12.2:

// activities.ts
export const sampleActivity = async (input: { pointer: number }) => {
  return { pointer: 7 }
}

// workflow.ts
import { proxyActivities } from "@temporalio/workflow";
import type * as activities from "./activities.js";

const { sampleActivity } = proxyActivities<typeof activities>({})

export const workflow = async () => {
  let pointer: null | number = 0

  do {
    const result = await sampleActivity({ pointer })
    pointer = result.pointer
  } while (pointer !== null)
}

This issue might be caused by changes to the typing of the proxyActivites function introduced in #1657

// Before PR 1657
export type ActivityInterfaceFor<T> = {
  [K in keyof T]: T[K] extends ActivityFunction ? T[K] : typeof NotAnActivityMethod;
};

// After PR 1657
export type ActivityInterfaceFor<T> = {
  [K in keyof T]: T[K] extends ActivityFunction ? ActivityFunctionWithOptions<T[K]> : typeof NotAnActivityMethod;
};

Environment/Versions

  • Temporal Version: SDK version 1.12.2+

Workaround

The simplest workaround is to explicitly type the variable storing the return value, e.g:

const result: { pointer: number } = await sampleActivity({ pointer })

Another is to rearrange the code, which works well in some cases:

let { pointer } = await sampleActivity({ pointer: 0 })

while (pointer !== null) {
  const result = await sampleActivity({ pointer })
  pointer = result.pointer
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions