【问题标题】:In Typescript, how do I set the type of an object to reflect a list of a class's properties?在 Typescript 中,如何设置对象的类型以反映类属性的列表?
【发布时间】: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 中进行测试。

标签: typescript typescript-typings


【解决方案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

【讨论】:

  • 我希望找到另一个解决方案的主要原因是,我可以使用该类型作为传入对象的泛型。但这是我目前的做法。
猜你喜欢
  • 1970-01-01
  • 2021-08-30
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
相关资源
最近更新 更多