如何在定义为“any"的第三方 TypeScript 接口中增加属性? [英] How can I augment a property within a third-party TypeScript interface defined as "any"?
问题描述
给定一个像这样定义的第三方 TypeScript 模块:
Given a third-party TypeScript module defined like this:
// in /node_modules/third-party-module/index.d.ts
declare module 'ThirdPartyModule' {
export interface ThirdPartyInterface {
data: any;
}
}
如何扩充此模块以更严格地键入 data
属性?
How can I augment this module to more strictly type the data
property?
我已经试过了:
// in /app/typings.d.ts
declare module 'ThirdPartyModule' {
interface IMyCustomType {}
interface ThirdPartyInterface {
// causes a compiler error: Subsequent property declarations
// must have the same type. Property 'data' must be of type
// 'any', but here has type 'IMyCustomType'.
data: IMyCustomType;
}
}
但这给了我一个编译器错误:后续的属性声明必须具有相同的类型.属性‘data’必须是‘any’类型,但这里有‘IMyCustomType’类型."
But this gives me a compiler error: "Subsequent property declarations must have the same type. Property 'data' must be of type 'any', but here has type 'IMyCustomType'."
如果第三方模块将属性定义为实际类型,如下所示:
If the third-party module instead defined the property as an actual type, like this:
// in /node_modules/third-party-module/index.d.ts
declare module 'ThirdPartyModule' {
interface IAnotherThirdPartyInterface {
something: string;
}
interface ThirdPartyInterface {
data: IAnotherThirdPartyInterface;
}
}
我可以简单地让我的 IMyCustomType
接口扩展这个第三方类型:
I could simply make my IMyCustomType
interface extend this third party type:
// in /app/typings.d.ts
declare module 'ThirdPartyModule' {
interface IMyCustomType extends IAnotherThirdPartyInterface {}
interface ThirdPartyInterface {
data: IMyCustomType;
}
}
但是,由于类型定义为any
,我无法扩展它:
However, since the type is defined any
, I can't extend it:
// causes a compiler error: 'any' only refers to a type,
// but is being used as a value here.
interface IMyCustomType extends any {}
推荐答案
虽然您不能重新定义属性,但另一种方法是定义一个新属性,并用这个新属性扩充原始对象.虽然此解决方案并不普遍适用,但如果该属性在类上,则可以完成.在您的情况下,您在评论中提到 hapi
.由于该属性位于 Server
类上,我们可以定义该属性的新类型版本.
While you can't redefine the property, an alternative would be to define a new property, and augment the original object with this new property. While this solution is not generally applicable, if the property is on a class it can be done. In your case you mention in the comments hapi
. Since the property is on the Server
class we can define a new typed version of the property.
hapi.augment.ts
import * as Hapi from 'hapi'
declare module 'hapi' {
export function server(cfg: any): Hapi.Server;
interface Server {
typedApp: {
myData: string
}
}
}
Object.defineProperty(Hapi.Server.prototype, 'typedApp', {
enumerable: false,
get(this: Hapi.Server){
return this.app;
},
set(this: Hapi.Server, value: any){
this.app = value;
}
});
usage.ts
import * as Hapi from 'hapi'
import './hapi.augment'
const server = new Hapi.Server()
server.connection({ port: 3000, host: 'localhost' });
server.start();
server.typedApp.myData = "Here";
server.route({
method: 'GET',
path: '/',
handler: function (request, reply) {
reply(request.server.typedApp.myData);
}
});
这篇关于如何在定义为“any"的第三方 TypeScript 接口中增加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!