如何覆盖打字稿中的属性?

Posted

技术标签:

【中文标题】如何覆盖打字稿中的属性?【英文标题】:How do I override a property in typescript? 【发布时间】:2016-10-08 23:15:27 【问题描述】:

由于当前的语言限制,这可能是不可能的,但我使用的是最新的 TS (1.8.10),并且遇到了 ui-grid 类型的问题。 IGridOptions 上的 isRowSelectable 属性被定义为一个可选的布尔值,但文档说它是一个函数(确实如此)。我正在尝试将布尔属性覆盖为返回布尔值的函数。

通常,我只是扩展打字界面并做我需要的事情,但在这种情况下这不起作用。这是我所拥有的:

interface ISelectionGridOptions extends IGridOptions 
  isRowSelectable: (row: IGridRowOf<Profile>) => boolean;

IGridOptions 中的相关字段在哪里:

export interface IGridOptions 
  ...
  isRowSelectable?: boolean
  ...

我得到的错误是:

(41,11): error TS2430: Interface 'ISelectionGridOptions' incorrectly extends interface 'IGridOptionsOf<any>'.
  Types of property 'isRowSelectable' are incompatible.
    Type '(row: IGridRowOf<Profile>) => boolean' is not assignable to type 'boolean'.

没有修复核心类型定义,有没有办法在我的代码中解决这个问题?

【问题讨论】:

如果接口将isRowSelectable 声明为布尔值,那么您不能用函数“覆盖”它,因为布尔值不可调用。 好的,这是有道理的。如果您想将此作为答案进行回复,我很乐意将其标记为这样。谢谢。 有点迂腐,它不是因为布尔值不可调用,而是因为不能将函数分配给布尔值。函数 peg 无法放入布尔孔中,反之亦然。 另见:Overriding interface property type defined in Typescript d.ts file 【参考方案1】:

您可以使用实用程序类型Omit: https://www.typescriptlang.org/docs/handbook/utility-types.html#omittk

interface ISelectionGridOptions extends Omit<IGridOptions, 'isRowSelectable'> 
  isRowSelectable: (row: IGridRowOf<Profile>) => boolean;

【讨论】:

IMO,这不是正确的答案或解决方案。当然,这是一种解决方法,但它不能解决或解决问题的根本原因,我会鼓励任何工程师追求这一点。 同意它不能解决 OP 的问题,但这对于代码重用非常有用,特别是如果您想重用来自第三方的东西。 +1【参考方案2】:

如果类型定义不正确,则不能使用覆盖来修复它们 - 类型系统正确地将其视为错误。在类型化语言中,防止子类更改类型签名是一件好事。这里的问题是损坏的类型定义。如果修复 def 不切实际,并且问题仅出现在代码中的几个地方,则可以使用强制转换为 any 来禁用类型检查,直到修复 defs:

var foo = <boolean> (<any>bar).isRowSelectable(args);
bar.isRowSelectable = <any>foo; 

只需发表评论,解释发生了什么。当然,最好修复类型 defs。

注意:它会中断,就像错误所说的那样,因为函数不能分配给布尔值。函数 peg 无法放入布尔孔中,反之亦然

【讨论】:

是的,我今天做了成人礼并提交了 PR:github.com/DefinitelyTyped/DefinitelyTyped/pull/9594【参考方案3】:

TS 3.5+ 更新

您可以将此实用程序类型添加到您的项目中:

type Modify<T, R> = Omit<T, keyof R> & R;

然后像这样使用它:

type ISelectionGridOptions = Modify<IGridOptions, 
  isRowSelectable: (row: IGridRowOf<Profile>) => boolean;
>

Demo in TS Playground

进一步阅读

Overriding interface property type defined in Typescript d.ts file How to override type properties in TypeScript

【讨论】:

以上是关于如何覆盖打字稿中的属性?的主要内容,如果未能解决你的问题,请参考以下文章

打字稿中对象文字的类型安全合并

打字稿中的可选属性类

如何在打字稿中对模型接口进行单元测试?

如何在打字稿中的猫鼬userschema.methods中使用“this”

如何使用打字稿中的查找来推断类型化的 mapValues?

打字稿中的错误:“AngularFireStorageModule”类型上不存在属性 .ref