Javascript 将Typescript泛型约束到对象

Javascript 将Typescript泛型约束到对象,javascript,typescript,Javascript,Typescript,大家好 我不太熟悉,但以下是我想要实现的目标,我目前正在努力: 使用下面定义的函数createObject创建一个对象。作为参数,您只能传入对象类型的参数 它返回传入的参数,但被类型和详细信息属性修改) 这就是我到目前为止所做的。 在函数createObject中,options.type、options.showdeail、options.detail以红色突出显示。Typescript抱怨: [第4行]类型“T”上不存在属性“type” [第3行]类型“T”上不存在属性“showDetai

大家好

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

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

它返回传入的参数,但被类型和详细信息属性修改)

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

在函数
createObject
中,
options.type、options.showdeail、options.detail
以红色突出显示。Typescript抱怨:

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

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

[第5行,8]类型“T”上不存在属性“detail”

此外,返回泛型不会返回修改后的参数,而只返回输入参数。也就是说,我不会得到关于
newObj
的细节/类型属性的Typescript提示

我的IDE只为age和name属性提供类型提示。正如预期的那样,因为我错误地返回了输入参数

如何获得合适的typescript解决方案?
谢谢大家!

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

接口选项扩展{
类型?:字符串,
showDetail?:布尔值,
细节?:字符串
}
函数createObject(选项:T):T和OptionExtensions{
让选项扩展:T&OptionExtensions=options;
如果(!optionsExtended.type){
如果(选项扩展。显示详细信息){
optionsExtended.type='text';
optionsExtended.detail='Some detail';
}否则{
optionsExtended.type='simple';
选项extended.detail='';
}
}
返回选项扩展;
}
设foo=createObject({
姓名:“史蒂文”,
年龄:28
});
这是一个例子。您可以检查
foo
是否具有您期望的所有属性(通过编写“foo.”并查看建议)

脚注1:
我的意思是因为TypeScript有很好的功能,它允许您在不显式编写类型和创建接口的情况下工作,但时间不会太长。想一想如何用OOP语言编写东西,然后进行适当的抽象和建模。

如果泛型对象被用作类型,那么必须扩展具有这些属性名称的类型:创建该接口并扩展该接口。其次,您的
objectConfig
构造与您扩展的属性的类型不匹配<代码>某些细节作为字符串将导致您将年龄作为数字类型传递时出现问题。不过,您可能希望保留
,否则,如果插入例如数字或字符串,您将不会被注意到。
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);
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
});