首页 > 解决方案 > TS 推断出我的泛型函数的未知返回类型,我该如何防止呢?以一般的方式?

问题描述

我知道标题听起来很混乱。我不知道如何用一句话来解释我的问题。但是这段代码解释了我的意思:

// This is the class that I want to extend further on.
class User {
    public name: string

    constructor(name: string) {
        this.name = name
    }
}

type Constructable<InstanceType> = {
    new (...args: any[]): InstanceType
}

type MyFactory<InstanceType> = {
    newWithRandomName(): InstanceType
}

type ExtendedClass<InstanceType, ClassType extends Constructable<InstanceType>> = ClassType & MyFactory<InstanceType>

// This is the function that I use to extend the class.
function extendClass<InstanceType, ClassType extends Constructable<InstanceType>>(
    classType: ClassType
): ExtendedClass<InstanceType, ClassType> {
    return new Proxy(classType, {
        get(target, prop, receiver) {
            if (prop === "newWithRandomName") {
                return () => new classType("Joe Random")
            }

            return Reflect.get(target, prop, receiver)
        }
    }) as ExtendedClass<InstanceType, ClassType>
}

const ExtendedUser = extendClass(User)

// Both of these lines work as expected
let user1 = new User("John Doe")
let user2 = new ExtendedUser("Jane Doe")

// But this line returns an unknown type,
// even though I thought I clearly defined
// what type should be returned, didn't I?
let user3 = ExtendedUser.newWithRandomName()

console.log(user3.name)

这是一个你可以玩的游乐场

标签: typescripttypescript-generics

解决方案


您不需要两个通用参数,请看下面:

// This is the class that I want to extend further on.
class User {
  public name: string

  constructor(name: string) {
    this.name = name
  }
}

type MyFactory<T> = {
  newWithRandomName(): T
}

type ExtendedClass<T extends new (...args: any[]) => any> = T & MyFactory<T>

// This is the function that I use to extend the class.
function extendClass<ClassType extends new (...args: any[]) => any>(
  classType: ClassType
): ExtendedClass<ClassType> {
  return new Proxy(classType, {
    get(target, prop, receiver) {
      if (prop === 'newWithRandomName') {
        return () => new classType('Joe Random')
      }

      return Reflect.get(target, prop, receiver)
    }
  }) as ExtendedClass<ClassType>
}

const ExtendedUser = extendClass(User)

// Both of these lines work as expected
const user1: User = new User('John Doe')
const user2: User = new ExtendedUser('Jane Doe')

// But this line returns an unknown type,
// even though I thought I clearly defined
// what type should be returned, didn't I?
const user3: User = ExtendedUser.newWithRandomName()

console.log(user3.name)



推荐阅读