将Typescript泛型约束为对象

时间:2019-03-13 14:17:27

标签: javascript typescript

大家好,

我对Typescript不太熟悉,但是我想实现以下目标,而我目前正在努力:

使用下面定义的功能createObject创建一个对象。作为参数,您只能传入对象类型的参数。

它返回传入的参数,但由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);

在功能createObject中,options.type, options.showDetail, options.detail用红色突出显示。打字稿抱怨:

  

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

     

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

     

[第5行,第8行]类型'T'不存在属性'detail'。

此外,返回泛型将不会返回修改后的参数,而只会返回输入参数。即我不会得到有关newObj的detail / type属性的Typescript提示。

我的IDE仅给我有关age和name属性的类型提示。符合预期,因为我错误地只返回了输入参数。

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

1 个答案:

答案 0 :(得分:2)

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

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语言编写东西,然后建立适当的抽象和模型。