超全模态模型 × Harness 升级,升级解锁 ArkClaw,最新支持 DeepSeek-V4 系列与 GLM-5.1
你尝试的代码写法有误,因为在类型定义中不能引用未完全定义的类型的键,且条件判断的位置不对。要实现“每一层嵌套都只有string类型键”的对象类型,可以通过递归结合联合类型来完成,同时也可以实现你提到的“非对象类型”(Not)。步骤1:定义“非对象类型” #TypeScript中可以通过Exclude工具类型实现“排除object类型后的所有类型”,也就是你要的Not<object>:// 排除所有object类型,得到原始类型、null、undefined等非对象类型 type NotObject = Exclude<unknown, object>; 注:object类型在TypeScript中包含普通对象、数组、函数、Set/Map等引用类型,NotObject会包含string、number、boolean、null、undefined、bigint、symbol这些类型。如果需要排除null/undefined,可以调整为:type NotObject = Exclude<unknown, object | null | undefined>; 步骤2:定义递归的string键对象类型 #基于NotObject,我们可以定义递归类型,要求每一层的键都是string,值要么是非对象类型,要么是符合同样规则的递归对象:type RecursiveStringKeyObject = { [key: string]: NotObject | RecursiveStringKeyObject; }; 也可以用Record工具类型简化写法:type RecursiveStringKeyObject = Record<string, NotObject | RecursiveStringKeyObject>; 验证效果 #符合要求的对象(仅string键,嵌套对象也遵循规则):const validData: RecursiveStringKeyObject = { username: "zhangsan", age: 28, profile: { email: "zhangsan@example.com", address: { city: "Beijing", zip: 100000 } } }; 不符合要求的对象(包含symbol键)会被TypeScript报错:const testSymbol = Symbol("id"); const invalidData: RecursiveStringKeyObject = { [testSymbol]: "123" // 类型错误:symbol类型的键不符合string键要求 }; 补充:如果需要允许数组/函数等引用类型作为叶子节点 #上面的NotObject排除了所有object类型,所以数组、函数等会被视为不合法的类型。如果需要允许这些类型作为叶子节点(仅普通对象需要递归遵循string键规则),可以调整递归逻辑:// 递归类型:普通对象则递归应用规则,允许数组、函数等作为叶子节点 type RecursiveStringKeyObject = { [key: string]: | Exclude<unknown, object> | Array<any> | Function | Set<any> | Map<any> | RecursiveStringKeyObject; }; 内容的提问来源于stack exchange,提问作者shau-kote
TypeScript中可以通过Exclude工具类型实现“排除object类型后的所有类型”,也就是你要的Not<object>:
Exclude
Not<object>
// 排除所有object类型,得到原始类型、null、undefined等非对象类型 type NotObject = Exclude<unknown, object>;
注:object类型在TypeScript中包含普通对象、数组、函数、Set/Map等引用类型,NotObject会包含string、number、boolean、null、undefined、bigint、symbol这些类型。如果需要排除null/undefined,可以调整为:
object
NotObject
type NotObject = Exclude<unknown, object | null | undefined>;
基于NotObject,我们可以定义递归类型,要求每一层的键都是string,值要么是非对象类型,要么是符合同样规则的递归对象:
type RecursiveStringKeyObject = { [key: string]: NotObject | RecursiveStringKeyObject; };
也可以用Record工具类型简化写法:
Record
type RecursiveStringKeyObject = Record<string, NotObject | RecursiveStringKeyObject>;
const validData: RecursiveStringKeyObject = { username: "zhangsan", age: 28, profile: { email: "zhangsan@example.com", address: { city: "Beijing", zip: 100000 } } };
const testSymbol = Symbol("id"); const invalidData: RecursiveStringKeyObject = { [testSymbol]: "123" // 类型错误:symbol类型的键不符合string键要求 };
上面的NotObject排除了所有object类型,所以数组、函数等会被视为不合法的类型。如果需要允许这些类型作为叶子节点(仅普通对象需要递归遵循string键规则),可以调整递归逻辑:
// 递归类型:普通对象则递归应用规则,允许数组、函数等作为叶子节点 type RecursiveStringKeyObject = { [key: string]: | Exclude<unknown, object> | Array<any> | Function | Set<any> | Map<any> | RecursiveStringKeyObject; };
内容的提问来源于stack exchange,提问作者shau-kote
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起
模型再升级,30秒超长叙事, 模态参考扩容
模型自由,工具不限,最新支持 Deepseek-V4 系列、GLM-5.3 系列
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列
大模型19元起,Al应用9.9元畅享,新人首购爆款尽享优惠