第22行的data怎么动态推断出与payload.data的类型一致?

第22行的data怎么动态推断出与payload.data的类型一致?

第22行的data怎么动态推断出与payload.data的类型一致?

阅读 846
avatarAI BotBETA

在大多数静态类型语言(如TypeScript)中,如果你希望一个变量(如data)能够动态地推断出与另一个变量(如payload.data)相同的类型,你通常需要使用一些类型系统提供的功能或技巧。然而,直接“动态推断”类型在编译时是行不通的,因为类型信息是在编译时确定的,而“动态”通常指的是运行时行为。

不过,有几种方法可以在TypeScript(或类似支持类型推断的语言)中接近这种效果:

  1. 类型断言(Type Assertions):
    如果你确信datapayload.data在运行时具有相同的类型,你可以使用类型断言来告诉TypeScript编译器datapayload.data的类型。例如:

    let data: any = payload.data; // 假设这里先使用any作为类型
    const dataTyped = data as typeof payload.data; // 类型断言

    但注意,typeof payload.data在TypeScript中并不是这样使用的,因为typeof运算符在TypeScript中返回的是类型本身(如stringnumber等),而不是变量值的类型。所以上面的代码仅作示例,实际上并不工作。

  2. 泛型(Generics):
    如果payload来自一个泛型函数或类,并且其data属性被正确地类型化,那么你可以通过泛型来确保data具有相同的类型。

    interface Payload<T> {
      data: T;
    }
    
    function processData<T>(payload: Payload<T>) {
      let data: T = payload.data; // 这里data的类型自动与payload.data相同
      // 使用data...
    }
  3. 条件类型(Conditional Types)和映射类型(Mapped Types):
    对于更复杂的类型推断,你可能需要使用条件类型或映射类型来根据payload.data的类型来推断data的类型。但这通常用于更高级的场景,比如类型映射或类型转换。
  4. 接口继承类型别名
    如果你知道payload的结构并且想复用这些类型信息,你可以通过定义接口或类型别名来继承这些类型。

    interface BaseData {
      // 定义一些共有属性
    }
    
    interface PayloadWithData<T extends BaseData> {
      data: T;
    }
    
    let payload: PayloadWithData<{ id: number, name: string }> = { data: { id: 1, name: "Example" } };
    let data: typeof payload.data = payload.data; // 这里typeof用于示例,实际不需要

在实际应用中,通常推荐使用泛型来处理这种情况,因为它提供了类型安全性和灵活性。如果你确实需要在运行时处理类型,并且需要动态地根据payload.data的类型来更改data的类型,那么你可能需要考虑使用运行时类型检查(如instanceof或自定义类型检查函数)结合类型断言。但请注意,这将牺牲一些TypeScript提供的编译时类型安全性。

2 个回答

如果你想要在运行时进行类型验证,可以使用 Zod

如果你仅是需要类型提示和代码补全,参考 @寸寸青丝愁华年 的回答使用泛型。

export class ResultData<T = any> {
  message?: string;
  data?: T;
  success!: boolean;
  constructor(event: any, params: ResultData & { status: number }) {
    console.log(event);
    const { status, ...rest } = params;
    Object.assign(this, rest);
  }

  static OK<T>(event: string, params: Partial<ResultData<T>> & { status: number }) {
    return new ResultData<T>(event, { ...params, success: true });
  }
}

function promise(): Promise<{ id: number, name: string }> {
  return new Promise((resolve) => {
    resolve({ id: 1, name: 'zsh' })
  })
}

async function result() {
  const name = await promise();
  const result = ResultData.OK('', {
    status: 200,
    data: {
      id: 1,
      name: 'zsh'
    }
  })
  const data = result.data?.id!; // number
}

泛型符合你的预期吗?

推荐问题
logo
Microsoft
子站问答
访问
宣传栏