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

如何让TypeScript从普通JavaScript对象推断类型?库开发问询

Is This Requirement Achievable?

Absolutely, this is totally doable! You can deliver full type safety and IntelliSense for both TypeScript and JavaScript users by leveraging TypeScript's advanced type system features. Let's break down how to implement this:

1. TypeScript User Experience

For TS users who explicitly pass a generic type (like Collection<Person>), we can build the Collection class to enforce the type on the object returned by get().

Implementation Code

// Generic Collection class to enforce type safety
class Collection<T> {
  get(id: number): T {
    // Replace with your actual database fetch logic
    return {} as T; // Type assertion used for demonstration
  }
}

// User-defined interface matching their schema
interface Person {
  firstName: string;
  age?: number;
}

// User's usage
const personCollection = new Collection<Person>();
personCollection.get(12).firstName; // ✅ No errors, full IntelliSense
personCollection.get(12).test; // ❌ TS compilation error (property 'test' doesn't exist on type 'Person')

This works because the generic type T is strictly enforced on the return value of get(), so TypeScript validates all property accesses against the user's defined type.

2. JavaScript User Experience

For JS users who only provide a Schema object, we can use TypeScript's type inference from object literals and mapped types to generate a type from the Schema. VSCode will use this generated type to show IntelliSense and warn about invalid properties.

Step 1: Define Schema Base Types

First, we need to type the Schema structure so TypeScript can interpret it correctly:

type PropertyDefinition = {
  name: string;
  type: 'string' | 'number';
  primary?: boolean;
  required?: boolean;
};

type DatabaseSchema = {
  name: string;
  properties: PropertyDefinition[];
};

Step 2: Convert Schema to Entity Type

We'll create a mapped type that transforms the Schema into a corresponding object type, respecting required/optional flags and property types:

type SchemaToEntityType<S extends DatabaseSchema> = {
  [PropName in S['properties'][number]['name']]: 
    // Check if the property is marked as required
    PropName extends Extract<S['properties'][number], { name: PropName; required: true }>
      // Map required properties directly to their type
      ? Extract<S['properties'][number], { name: PropName }>['type'] extends 'string'
        ? string
        : number
      // Mark optional properties as possibly undefined
      : Extract<S['properties'][number], { name: PropName }>['type'] extends 'string'
        ? string | undefined
        : number | undefined;
};

Step 3: Build a Type-Inferred Collection Factory

Instead of having users instantiate Collection directly, we'll create a factory function that accepts a Schema and automatically infers the entity type:

class Collection<T = unknown> {
  private schema?: DatabaseSchema;

  constructor(schema?: DatabaseSchema) {
    this.schema = schema;
    // Optional: Add runtime validation logic here using the schema
  }

  get(id: number): T {
    // Replace with your actual database fetch logic
    return {} as T; // Type assertion for demonstration
  }
}

// Factory function to enable automatic type inference
function createCollection<S extends DatabaseSchema>(schema: S): Collection<SchemaToEntityType<S>> {
  return new Collection(schema) as Collection<SchemaToEntityType<S>>;
}

JavaScript User Usage

Now JS users can pass their Schema object and get full IntelliSense in VSCode:

// JS user's schema definition
const personSchema = {
  name: 'person',
  properties: [
    { name: 'firstName', type: 'string', primary: true, required: true },
    { name: 'age', type: 'number', required: false }
  ]
};

const personCollection = createCollection(personSchema);
personCollection.get(12).firstName; // ✅ IntelliSense shows this property
personCollection.get(12).test; // ❌ VSCode warns "property 'test' does not exist"

Even though JavaScript doesn't compile to enforce this, VSCode uses TypeScript's language service to analyze the Schema object and provide accurate hints—exactly what you're aiming for.

Bonus: Optional Runtime Validation

For JS users, you can add runtime checks in the get() method to ensure returned objects only contain schema-defined properties, or throw errors when accessing invalid properties (though this isn't required for the IntelliSense functionality).


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:37:46