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

如何将Schema对象转换为等价TypeScript类型?编译器属性未识别问题

问题描述

能不能把下面的Schema对象:

const userSchema = {
  name: { type: String },
  age: { type: Number },
};

转换成等价的TypeScript类型:

type userType = {
  name: string;
  age: number
}

我试过基于Schema创建对象后用typeof获取类型,但编译器识别不了属性。以下是我的尝试代码:

type schemaType = {
  [key: string]: {
    type?: StringConstructor | DateConstructor | NumberConstructor;
  };
};

type resultType = {
  [key: string]: String | Date | Number;
};

const createPropsFromSchema = (schema: schemaType) => {
  const result = { id: "" } as resultType;

  Object.keys(schema).forEach((key) => {
    if (schema[key].type == String) {
      result[key] = "";
    } else if (schema[key].type == Date) {
      result[key] = new Date();
    } else if (schema[key].type == Number) {
      result[key] = 0;
    }
  });

  return result;
};

const userSchema = {
  name: { type: String },
  age: { type: Number },
};

const userProps = createPropsFromSchema(userSchema);

console.log(userProps.name); //为什么编译器没有提示"name"?
解决方案

要实现这个需求,得让TypeScript保留Schema的键名和对应类型信息,用泛型+条件类型就能解决:

1. 定义类型映射工具

先创建一个类型,把构造函数类型转换成对应的TS基础类型:

type ConstructorToType<T> = 
  T extends StringConstructor ? string :
  T extends NumberConstructor ? number :
  T extends DateConstructor ? Date :
  never;

再创建泛型类型,把Schema结构直接映射成目标类型:

type SchemaToType<S> = {
  [K in keyof S]: ConstructorToType<S[K]['type']>;
} & { id: string }; // 对应你代码里默认的id字段

2. 改造工厂函数

把createPropsFromSchema改成泛型函数,让它能根据传入的Schema推断出返回值的具体类型:

const createPropsFromSchema = <S extends Record<string, { type: StringConstructor | NumberConstructor | DateConstructor }>>(schema: S) => {
  const result = { id: "" } as SchemaToType<S>;

  (Object.keys(schema) as Array<keyof S>).forEach((key) => {
    const field = schema[key];
    if (field.type === String) {
      result[key] = "" as ConstructorToType<typeof field.type>;
    } else if (field.type === Date) {
      result[key] = new Date() as ConstructorToType<typeof field.type>;
    } else if (field.type === Number) {
      result[key] = 0 as ConstructorToType<typeof field.type>;
    }
  });

  return result;
};

3. 使用示例

现在再调用函数,编译器就能正确识别userProps的属性和类型了:

const userSchema = {
  name: { type: String },
  age: { type: Number },
};

const userProps = createPropsFromSchema(userSchema);
// 此时userProps的类型是 { id: string; name: string; age: number }

console.log(userProps.name); // 编译器会提示name属性,类型为string

之前代码失效的原因

  • 你定义的schemaType是宽泛的索引签名{ [key: string]: ... },传入userSchema时,TypeScript会丢失具体键名(name、age)的信息,只知道这是个字符串键的对象。
  • resultType同样是宽泛的索引类型,所以返回的userProps在编译器看来只是{ [key: string]: String | Date | Number } & { id: string },没法确定具体有哪些属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:02:26