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

TypeScript:克隆现有接口并递归转换属性为string类型(含数组特殊处理)

Solution for Recursive Type Transformation in TypeScript

You can absolutely pull this off with pure TypeScript type definitions! The core is building a recursive type that handles primitive values, nested objects, and arrays separately. Here's the complete working solution:

// Helper type to recursively transform types into string-based structures
type DeepStringify<T> = 
  // Handle arrays: transform the element type instead of retaining the array structure
  T extends Array<infer U> ? DeepStringify<U> :
  // Handle objects: recursively process every nested property
  T extends object ? { [K in keyof T]: DeepStringify<T[K]> } :
  // Convert all primitive types directly to string
  string;

// Your desired CloneType, applying the deep string transformation to every property of the input model
type CloneType<Model> = {
  [K in keyof Model]: DeepStringify<Model[K]>;
};

How This Logic Works

Let’s break down each part of the solution:

  • Array Handling: The first conditional checks if the type is an array (T extends Array<infer U>). Using infer U extracts the array's element type, then we apply DeepStringify to that element. This is why your items property (originally Item[]) becomes the stringified version of Item instead of an array of strings.
  • Object Handling: The second conditional targets objects (arrays are already handled earlier, so we don’t reprocess them here). It creates a mapped type where every property of the object is recursively transformed with DeepStringify.
  • Primitive Handling: Any type that’s not an array or object (like number, boolean, etc.) gets converted straight to string.

Testing with Your Example

When applied to your original interfaces, this produces exactly the type you need:

interface A {
  innerA: InnerA;
  innerB: InnerB;
}
interface InnerA {
  items: Item[];
  name: string;
  counter: number;
}
interface InnerB {
  address: string;
  code: number;
}
interface Item {
  id: number;
}

const labels: CloneType<A> = {
  innerA: {
    items: { id: 'ID' },
    name: 'Some Name',
    counter: 'Some Counter'
  },
  innerB: {
    address: 'Address',
    code: 'Postal Code'
  }
};

// These type checks will work flawlessly
const postalCodeLabel: string = labels.innerB.code;
const itemIdLabel: string = labels.innerA.items.id;

What Was Missing in Your Original Attempt

Your initial CloneType only handled one level of nesting and didn’t account for arrays. It assumed every property was an object and mapped its fields to string, but didn’t recursively process deeper nested objects or handle the special array case you needed. The recursive DeepStringify helper fixes both of these gaps.

内容的提问来源于stack exchange,提问作者MrrrrMeowCat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:12:35