typescript 类型推断?

假设我有已知类型A、B、C定义如下:

class A {
    a!: string;
}

class B {
    b!: string;
}

class C {
    c!: string;
}

现在我定义了一个类型:

// 我希望这里的D能够自动推断
export type Root<D> = {
  deps: D;
  depsInstance: () => void
} & ThisType<{ depArray: D }>

声明变量指定类型:

// const root:Root<[A, B, C]> = {
//    deps: [{ a: 1 },{ b: 2 },{ c: 3 }]
//}

// 我希望这里不需要传入泛型 `<[typeof A, typeof B, typeof C]>`
const root: Root<[typeof A, typeof B, typeof C]> = {
  deps: [A, B, C],  // 由这里来决定 泛型D 类型, 有点儿像类型反向推断
  depsInstance: function () {
    // 这里的this实际上是 { { depArray: [A的实例,B的实例,C的实例] }}
    const [a, b, c] = this.depArray;
  }
}
阅读 2.1k
3 个回答
type SomeType = [1, 2];
export type Root<D = SomeType> = {
  deps: D;
  depsInstance: () => void
} & ThisType<{ depArray: D }>

let rr: Root = {
  deps: [1, 2],
  depsInstance() {
    const [a, b] = this.depArray;
    // a = 1, b = 2
  }
}

多看看自己的代码,你的 SomeType 可能类型就不对

class A {
  a!: string;
}

class B {
  b!: string;
}

class C {
  c!: string;
}

export type Root<D> = {
  deps: D;
  depsInstance: () => void;
} & ThisType<{ depArray: D }>;

通过辅助函数实现

function helper<T>(root: Root<T>) {
  return root;
}

class C {

}

const root = helper({
  deps: [{ a: 1 }, { b: 2 }, new C()] as const,
  depsInstance() {
    const [a, b, c] = this.depArray;
  },
});


image.png

查了一些资料,综合了一下,算是给解决了, 关键点在于用到了 infer 关键字。


class A {
  a!: string;
}

class B {
  b!: string;
}

class C {
  c!: string;
}

// 用这个辅助函数感觉很奇怪,再想想办法去掉这个
function helper<T>(root: Root<T>) {
  return root;
}

export type Root<D = object[]> = {
  deps: D;
  depsInstance: () => void
} & ThisType<{ depArray: { [K in keyof D]: D[K] extends new (...args: any) => infer I ? I : never } }>   

const root = helper({
  deps: [A, B, C] as const,
  depsInstance: function () {
    const [a, b, c] = this.depArray; // 这里能识别为 A,B,C的实例了
    
  }
})

image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进