为啥我不能在 Typescript 中扩展“任何”?
Posted
技术标签:
【中文标题】为啥我不能在 Typescript 中扩展“任何”?【英文标题】:Why can I not extend 'any' in Typescript?为什么我不能在 Typescript 中扩展“任何”? 【发布时间】:2016-09-16 10:43:27 【问题描述】:我想为使用外部库的类创建一个占位符接口。所以我做了:
export interface IDatabaseModel extends any
我宁愿这样做并稍后添加方法(例如 findAll()),而不是将我的所有类标记为“任何”,然后必须手动搜索并将数百个特定位置中的“任何”替换为“IDatabaseModel”。
但编译器抱怨找不到“任何”。
我做错了什么?
【问题讨论】:
我认为您对接口的工作方式有些困惑;如果您使用上面的代码,您仍然需要通过将any
替换为IDatabaseModel
才能应用它。
是的,但是我现在可以轻松地开发应用程序。稍后添加确切的方法并删除 any 以使打字更加健壮。但是,如果我等 3 个月,直到我们有 1000 个文件并尝试找到合适的 'any's 来替换 IDatabaseModel,那将是不切实际的
你可以这样写,但是 IDatabaseModel 不像any
那样工作: type Any = any;导出接口 IDatabaseModel 扩展 Any
【参考方案1】:
any
类型是一种选择退出类型检查的方法,因此在进行类型检查的环境中使用它是没有意义的。
您可以在使用时将方法添加到接口中:
export interface IDatabaseModel
findAll(): any;
编辑:请参阅Paleo's answer 同时使用类型别名。
【讨论】:
这看起来可以忍受。但是没有别的办法了吗?【参考方案2】:"any" 是一种类型,与其他基本类型不同,它似乎没有接口。鉴于它是某种通配符,我无法想象“任何”的接口可以包含什么。
【讨论】:
一个例子:让 TypeScript 知道用户已经向“对象”原型添加了一个函数。这样,输入("something" as any).MyCustomFunction()
将按预期显示MyCustomFunction()
的信息。【参考方案3】:
具有any
的别名
我想做一个占位符界面
使用别名:
type IDatabaseModel = any;
或带有索引签名 [从 2017 年 8 月开始编辑]
Since TypeScript 2.2,属性访问语法obj.propName
允许带有索引签名:
interface AnyProperties
[prop: string]: any
type MyType = AnyProperties &
findAll(): string[]
let a: MyType
a.findAll() // OK, with autocomplete
a.abc = 12 // OK, but no autocomplete
【讨论】:
这太棒了。谢谢! 这几乎完全是我想做的——也就是说,引用我稍后会充实的类型。唯一的问题是它全有或全无。如果我使用type MyThing = any;
,我可以在任何地方引用MyThing
而不会出错,但我没有得到 Intellisense 帮助。如果我使用interface MyThing
,我可以添加属性/方法,但引用我尚未添加的任何内容都会显示为错误。是否有“两全其美”不会发出错误(如any
)但会自动完成我有时间描述的任何属性?
@Coderer 在 2016 年这是不可能的。现在它是。我刚刚编辑。 :)
太棒了!非常适合我的用例。【参考方案4】:
2020 年 TLDR:
而不是extends any
尝试extends Record<string, any>
。
加长版:
在某些情况下,extends any
在 TypeScript 中仍然有效。但是,在 TypeScript 3.9 中,it is interpreted in a more conservative way.
@Paleo 在他的回答中创建了AnyProperties
接口。现在可以用Record 将其重写为extends Record<string, any>
。
【讨论】:
以上是关于为啥我不能在 Typescript 中扩展“任何”?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能在 ThreeJS Typescript 项目中创建 Face3
在 TypeScript 中扩展另一种类型的任何类型的参数?