在 Typescript 中,如何设置对象的类型以反映类属性的列表?

Posted

技术标签:

【中文标题】在 Typescript 中,如何设置对象的类型以反映类属性的列表?【英文标题】:In Typescript, how do I set the type of an object to reflect a list of a class's properties? 【发布时间】:2021-12-13 21:18:40 【问题描述】:

这个例子是通用的和简单的,基本目标更复杂,但理解如何做到这一点很重要。

假设我有一堂课

class Foo 
  bar: string;
  baz: number;
  bob: any; // could be a function

  bad() 
    return true;
  ;

我有一个函数

const init = (options: InitOptions, bar?: string, baz?: number, bob?: any) => 
  const foo = new Foo();
  foo.bar = bar ?? options.fallbacks.bar;
  foo.baz = baz ?? options.fallbacks.baz;
  foo.bob = bob ?? options.fallbacks.bob;

我如何创建类型 InitOptions 使其像这样运行

type InitOptions = 
  fallbacks = 
    bar: string;
    baz: number;
  

但不必重复自己。前任。 fallbacks 应该是一个对象,其中每个键都是来自 Foo 的属性。

【问题讨论】:

请注意:我不确定这是错字还是您的代码的一部分,但我相信您在最后一个代码示例中遗漏了一个 。 这看起来像是一个错字:const init(options: InitOptions, bar?: string, baz?: number) 您可以使用this,但它不会以编程方式将方法与函数值属性区分开来。例如,如果您有 class Foo a = () => 123; b() return 123 ; ,那么 OmitKeysMatching<Foo, Function> 将省略 ab。如果你对这种方法没意见,那么我可以写一个答案。如果没有,请edit 显示失败用例的问题。哦,您可能应该将代码编辑为没有拼写错误的minimal reproducible example(例如,const init(...) 是无效语法,fallbacks = 是无效语法);您应该在 IDE 中进行测试。 这能回答你的问题吗? How to create a type excluding instance methods from a class in typescript? 【参考方案1】:

是不是很简单?

class InitOptions 

  fallbacks: Foo;

澄清后更新:


  fallbacks: Pick<Foo, keyof Foo>;

【讨论】:

不,因为如果该类有方法,那么这些方法也会包含在内。 更新仍然显示方法作为选项,更新问题以将方法添加到类 是的,Pick 也会选择方法... @TylerClendenin:你不想包含方法有什么特别的原因吗?无论如何,如果这是绝对要求,您应该在问题中这么说。 @MontanaBurr 这是标题的一部分,我指定我想要类的属性【参考方案2】:

为什么不使用良好的旧 OO 继承范式?

class Fooable 
  bar: string = '';
  baz: number = 0;


class Foo extends Fooable 
  bad() 
    return true;
  


class InitOptions 
  fallbacks: Fooable =  bar: '', baz: 0 ;


function init(options: InitOptions, bar?: string, baz?: number) 
  const foo = new Foo();

  foo.bar = bar ?? options.fallbacks.bar;
  foo.baz = baz ?? options.fallbacks.baz;

  console.log(`Initialized with bar: $foo.bar, baz: $foo.baz`);


init( fallbacks:  bar: 'Hello', baz: 123  );
init( fallbacks:  bar: 'Hello', baz: 123  , 'World', 456);

当使用 ts-node 10.2.1 运行时,它会得到:

Initialized with bar: Hello, baz: 123
Initialized with bar: World, baz: 456

【讨论】:

我希望找到另一个解决方案的主要原因是,我可以使用该类型作为传入对象的泛型。但这是我目前的做法。

以上是关于在 Typescript 中,如何设置对象的类型以反映类属性的列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Typescript 和 useState 将类型对象设置为 React 的初始值?

如何在 TypeScript 中获取 JSON 文件上的 Object.keys 时设置类型?

如何在 TypeScript 中为对象动态分配属性?

如何在 TypeScript 中为对象动态分配属性?

TypeScript,啥是对象文字的调用签名以及它们如何与泛型类型一起使用?

在TypeScript中如何防止属性被添加到一个空对象中?