简体   繁体   English

将Typescript泛型约束为对象

[英]Constrain Typescript generics to object

Hi guys, 嗨,大家好,

I'm not that familiar with Typescript , but here is the following I want to achieve, and I'm currently struggling with: 我对Typescript不太熟悉,但是下面是我想要实现的目标,并且我目前正在努力:

Create an object with the function createObject as defined below. 使用如下定义的函数createObject创建一个对象。 As argument you can pass in only a parameter of type Object. 作为参数,你可以在Object类型的唯一一个参数传递。

It returns the passed in argument, but modified by an type and detail property). 它返回传入的参数,但由type和detail属性修改。

This is, what I have done so far. 这就是我到目前为止所做的。

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
}

When I execute my function: 执行函数时:

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

const newObj = createObject(objectConfig);

Inside the function createObject , options.type, options.showDetail, options.detail are highlighted red. 在函数createObjectoptions.type, options.showDetail, options.detail用红色突出显示。 Typescript complains about: 打字稿抱怨:

[Line 4] Property 'type' does not exist on type 'T'. [第4行]类型“ T”上不存在属性“类型”。

[Line 3] Property 'showDetail' does not exist on type 'T'. [第3行]类型'T'不存在属性'showDetail'。

[Line 5, 8] Property 'detail' does not exist on type 'T'. [第5、8行]类型'T'不存在属性'detail'。

Furthermore, returning the Generic, won't return the modified argument, instead just the input argument. 此外,返回泛型将不会返回修改后的参数,而只会返回输入参数。 Ie I won't get Typescript hints about the detail/type property of newObj . 即,我不会得到有关newObj的detail / type属性的newObj

My IDE just gives me type hints for the age and name property. 我的IDE仅给我有关age和name属性的类型提示。 As expected since I return erroneously just the input argument. 符合预期,因为我错误地仅返回了输入参数。

How can I get a proper typescript solution? 如何获得适当的打字稿解决方案? Thank you! 谢谢!

Well... The problem is you are writing TypeScript as if it is just like JavaScript. 好吧...问题是您正在编写TypeScript,就好像它就像JavaScript一样。 That's not how it works. 那不是它的工作原理。 Here's a solution that just works but you need to start writing TypeScript like you write any other OOP language 1 . 下面是刚工作的解决方案,但你需要一个像你写的任何其他OOP语言1开始编写打字稿。

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
});

Here's a demo . 这是一个演示 You can check foo has all properties that you would expect (by writing "foo." and seeing the suggestions). 您可以检查foo是否具有所需的所有属性(通过编写“ foo。”并查看建议)。

Footnote 1: By this I mean because TypeScript has nice type inference and duck typing it will allow you to make things work without explicitly writing types and making interfaces but not for too long. 脚注1:我的意思是因为TypeScript具有不错的类型推断鸭子类型,它使您无需显式地编写类型和创建接口就可以使事情正常运行,但是时间不会太长。 Think how would you write things in a OOP language and then make appropriate abstractions and models. 想想如何用OOP语言编写事物,然后制定适当的抽象和模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM