You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为返回函数包装器的原生JS工厂函数编写d.ts遇类型传递问题

Typing a Chainable Factory Function in TypeScript

To properly type your chainable factory function and preserve intermediate types through each stage, you'll need to use generics to carry type information from one function to the next. Here's a step-by-step solution tailored to your simplified function structure:

Step 1: Understand the Function Chain

Your factory has three distinct stages:

  1. Accepts x and y (with default 0), computes z = x + y
  2. Accepts a function fn that operates on z
  3. Accepts arbitrary arguments and returns a value based on fn(z) and those arguments

Step 2: Write the Type Definitions

Create a your-module.d.ts file with the following code. We'll use a helper type to compute the type of z, and generics to pass types through each stage:

// Helper type to compute the type of z = x + y
type Add<T, U> = 
  T extends string ? string : 
  U extends string ? string : 
  number;

export function factory<T, U = number>(x: T, y?: U): 
  // Stage 2: takes fn that accepts z and returns R
  <R>(fn: (z: Add<T, U>) => R) => 
  // Stage 3: takes args and returns a combined result (adjust based on your actual logic)
  <Args extends any[]>(...args: Args) => Promise<[R, Args]>;

Breakdown of the Types:

  • Add<T, U>: Handles the type of z—adding a string to anything results in a string; otherwise, it's a number. Adjust this if your function supports other addition types (like bigints).
  • factory<T, U = number>: Generic over T (type of x) and U (type of y, defaulting to number since y has a default value of 0).
  • Stage 2: The returned function is generic over R (the return type of fn), ensuring fn receives the correct type of z.
  • Stage 3: The final function is generic over Args (the arguments passed to it), preserving their type in the return value.

Step 3: Test the Type Definitions

Here's how the types work in practice:

import { factory } from './your-module';

// Case 1: x and y are numbers
const stage1 = factory(5, 3); // z is typed as number (8)
const stage2 = stage1((z) => z * 2); // z is number, returns number (16)
const result = stage2('a', true); // result is Promise<[number, [string, boolean]]>

// Case 2: x is string, y is number
const stage1Str = factory('hello', 5); // z is typed as string ("hello5")
const stage2Str = stage1Str((z) => z.length); // z is string, returns number (6)
const resultStr = stage2Str(100, null); // result is Promise<[number, [number, null]]>

Adjust for Your Exact Logic

If your final function returns something different (e.g., not a Promise, or a different structure), modify the return type of the innermost function. For example, if the final function returns just the result of fn(z):

// Modified final stage return type
<Args extends any[]>(...args: Args) => R;

Or if fn returns a Promise:

// Stage 2: fn returns Promise<R>
<R>(fn: (z: Add<T, U>) => Promise<R>) => 
// Stage 3: returns Promise<R>
<Args extends any[]>(...args: Args) => Promise<R>;

内容的提问来源于stack exchange,提问作者Paul S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:34:31