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

如何使用TypeScript按条件限制类字段的访问权限

根据上下文限制TypeScript类实例的属性访问

要实现根据构造函数传入的上下文参数限制属性访问,不需要用infer,用泛型+映射/条件类型就能搞定,下面提供两种可行方案:

方案一:泛型类(保留类结构)

通过泛型绑定上下文类型,将非当前上下文的属性标记为never,访问时会触发类型警告:

type Context = 'birds' | 'mammals';

// 定义上下文与属性的映射关系
type ContextToAnimals = {
  birds: { chicken: string; duck: string };
  mammals: { dog: string; cat: string };
};

// 生成类的类型:保留当前上下文属性,其余设为never
type AnimalClass<C extends Context> = ContextToAnimals[C] & {
  [K in Exclude<keyof (ContextToAnimals['birds'] & ContextToAnimals['mammals']), keyof ContextToAnimals[C]>]: never;
};

class MyClass<C extends Context> implements AnimalClass<C> {
  readonly chicken: string | never;
  readonly duck: string | never;
  readonly dog: string | never;
  readonly cat: string | never;

  constructor(context: C) {
    if (context === 'birds') {
      // 类型断言解决赋值时的类型校验问题
      (this as MyClass<'birds'>).chicken = 'chicken';
      (this as MyClass<'birds'>).duck = 'duck';
    } else {
      (this as MyClass<'mammals'>).dog = 'dog';
      (this as MyClass<'mammals'>).cat = 'cat';
    }
  }
}

// 自动推断泛型为'birds'
const myClass = new MyClass('birds');
const chicken = myClass.chicken; // ✅ 正常,类型为string
const dog = myClass.dog; // ❌ 类型错误:类型为never,无法赋值

方案二:工厂函数(更简洁严格)

直接根据上下文返回不同的实例类型,非对应上下文的属性直接不存在,访问时提示属性不存在:

type Context = 'birds' | 'mammals';

// 定义不同上下文对应的实例类型
type BirdInstance = { readonly chicken: string; readonly duck: string };
type MammalInstance = { readonly dog: string; readonly cat: string };

// 条件类型根据上下文返回对应实例类型
type AnimalInstance<C extends Context> = C extends 'birds' ? BirdInstance : MammalInstance;

function createMyClass<C extends Context>(context: C): AnimalInstance<C> {
  if (context === 'birds') {
    return { chicken: 'chicken', duck: 'duck' } as AnimalInstance<C>;
  } else {
    return { dog: 'dog', cat: 'cat' } as AnimalInstance<C>;
  }
}

const birdClass = createMyClass('birds');
birdClass.chicken; // ✅ 正常
birdClass.dog; // ❌ 类型错误:属性'dog'不存在于类型'BirdInstance'

关键说明

  • 两种方案都不需要infer,infer主要用于在条件类型中提取未知的类型参数,这里通过明确的泛型和映射/条件类型就能实现需求。
  • 方案一更贴近你原本的类结构,方案二更简洁且类型限制更严格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 05:03:30