【问题标题】:Constrain Typescript generics to object将 Typescript 泛型约束为对象
【发布时间】:2019-03-13 14:17:26
【问题描述】:

大家好,

我对@9​​87654321@ 不太熟悉,但这是我想要实现的目标,我目前正在努力解决:

使用如下定义的函数createObject 创建一个对象。作为参数,您可以传入 Object 类型的参数。

它返回传入的参数,但由 type 和 detail 属性修改)。

这就是我到目前为止所做的。

function createObject<T extends object>(options: T): T {
  if (!options.type) {
    if (options.showDetail) {
      options.type = 'text';
      options.detail = 'Some detail';
    } else {
      options.type = 'simple';
      options.detail = '';
    }
  }
  return options
}

当我执行我的功能时:

const objectConfig = {
  name: 'Steven',
  age: 28,
}

const newObj = createObject(objectConfig);

在函数createObjectoptions.type, options.showDetail, options.detail 内部以红色突出显示。打字稿抱怨:

[第 4 行] 类型“T”上不存在属性“类型”。

[第 3 行] 类型“T”上不存在属性“showDetail”。

[第 5、8 行] 类型“T”上不存在属性“详细信息”。

此外,返回 Generic 不会返回修改后的参数,而只是返回输入参数。 IE。我不会得到关于 newObj 的 detail/type 属性的 Typescript 提示。

我的 IDE 只是给我年龄和名称属性的类型提示。正如预期的那样,因为我错误地只返回了输入参数。

如何获得合适的打字稿解决方案? 谢谢!

【问题讨论】:

  • 您的泛型对象被用作一种类型,因此您必须扩展具有这些属性名称的类型:创建该接口并扩展它。其次,您的 objectConfig 构造与您扩展的属性的类型不匹配。 Some detail 是一个字符串会导致您将 age 作为数字类型传递。

标签: javascript typescript


【解决方案1】:

嗯...问题是您正在编写 TypeScript,就好像它就像 JavaScript 一样。这不是它的工作原理。这是一个可行的解决方案,但您需要像编写任何其他 OOP 语言一样开始编写 TypeScript1

interface OptionExtensions {
    type?: string,
    showDetail?: boolean,
    detail?: string
}

function createObject<T extends object>(options: T): T & OptionExtensions {
    let optionsExtended: T & OptionExtensions = options;
    if (!optionsExtended.type) {
        if (optionsExtended.showDetail) {
            optionsExtended.type = 'text';
            optionsExtended.detail = 'Some detail';
        } else {
            optionsExtended.type = 'simple';
            optionsExtended.detail = '';
        }
    }
    return optionsExtended;
}

let foo = createObject({
    name: "Steven",
    age: 28
});

这是demo。您可以检查foo 是否具有您期望的所有属性(通过编写“foo.”并查看建议)。

脚注 1: 我的意思是因为 TypeScript 有很好的 type inferenceduck typing 它可以让你在不显式编写类型和制作接口的情况下让事情正常工作,但不会持续太久。想想您将如何用 OOP 语言编写内容,然后进行适当的抽象和模型。

【讨论】:

  • 你可能想保留&lt;T extends object&gt;,否则如果你插入例如你不会被注意到。一个数字或一个字符串。
猜你喜欢
  • 2018-12-22
  • 2021-11-01
  • 2021-01-30
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
相关资源
最近更新 更多