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

TypeScript:从函数类型获取实例类型及声明getInstance方法类型

Got it, let's break down these two TypeScript challenges step by step—they’re focused on constructor functions and their instance types, which come up a lot in class-based or factory-style code.

1. Extract Instance Type from a Function Type

TypeScript has a built-in utility type specifically for this: InstanceType<T>. It extracts the instance type of a constructor function type T (i.e., the type you get when you new up the function).

Example 1: Class Constructor

If you have a class, use typeof ClassName to get its constructor type, then pass that to InstanceType:

class Car {
  model: string;
  year: number;
  constructor(model: string, year: number) {
    this.model = model;
    this.year = year;
  }
}

// Extract the instance type of Car
type CarInstance = InstanceType<typeof Car>;
// CarInstance is equivalent to { model: string; year: number; constructor: typeof Car }

Example 2: Custom Constructor Type

If you’re working with a generic constructor type (common in factory functions), InstanceType still works seamlessly:

// Define a generic constructor type
type Constructor<T = {}> = new (...args: any[]) => T;

// Extract instance type from a constructor that returns { id: string }
type IdInstance = InstanceType<Constructor<{ id: string }>>;
// IdInstance is { id: string }
2. Implement getInstance Method on Function.prototype with Type Declarations

To add a getInstance method to all functions (and ensure TypeScript recognizes it with correct types), we need two things: a global interface extension for type declarations, and the actual method implementation.

Step 1: Declare the Type

First, extend the global Function interface to add getInstance. We’ll make it generic so it infers the instance type automatically:

// Define a reusable constructor type (matches any function that can be `new`ed)
type Constructor<T = {}> = new (...args: any[]) => T;

// Extend the global Function interface
declare global {
  interface Function {
    /**
     * Creates and returns a new instance of the constructor function
     * @param args Arguments to pass to the constructor
     * @returns A new instance of the constructor's type
     */
    getInstance<T extends Constructor>(this: T, ...args: ConstructorParameters<T>): InstanceType<T>;
  }
}
  • ConstructorParameters<T> extracts the argument types of the constructor, so TypeScript will enforce passing the correct args.
  • this: T ensures the method can only be called on a valid constructor function (TypeScript will throw an error if you try to call it on a non-constructor function like an arrow function).

Step 2: Implement the Method

Now add the actual implementation to Function.prototype. We’ll add a check to ensure we’re dealing with a valid constructor:

Function.prototype.getInstance = function(...args: any[]) {
  // Guard clause: Ensure this is a constructor function (has a prototype and is callable)
  if (typeof this !== 'function' || !this.prototype) {
    throw new Error('getInstance can only be called on constructor functions (classes or function constructors)');
  }

  // Create and return a new instance using the constructor and provided args
  return new this(...args);
};

Example Usage

Now you can use getInstance on any constructor, with full TypeScript type support:

class User {
  username: string;
  constructor(username: string) {
    this.username = username;
  }
}

// TypeScript infers `user` as type User
const user = User.getInstance('john_doe');
console.log(user.username); // "john_doe"

// If you pass the wrong args, TypeScript throws an error:
// User.getInstance(); // Error: Expected 1 arguments, got 0

Notes

  • Arrow functions can’t be used as constructors (they don’t have a prototype property), so calling getInstance on an arrow function will throw a runtime error (and TypeScript will flag it at compile time too).
  • This works with traditional function constructors too, not just classes:
    function Book(title: string) {
      this.title = title;
    }
    
    const book = Book.getInstance('The TypeScript Handbook');
    // book is typed as InstanceType<typeof Book> (has a `title` property)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:32:53