typescript - 模块扩充应该如何编译
问题描述
我理解模块扩充的概念。我可以编译一些东西,并且可以获得我想要的功能,除了我无法从我的扩充中检测到类型。这是对我正在做的事情的简化。
我有一堂课src/moviedb.ts
export class MovieDb {
// Implementation...
}
然后在src/endpoints/index.ts
import { MovieDb } from '../moviedb'
import Configuration from './methods/configuration'
import { RequestParams, RequestOptions } from '../types'
// Eventually there will be a lot of modules here
// They all share the same implementation,
// only their typings and configuration change
const endpointGroups = [
Configuration,
]
// Create the dynamic api methods
for (const group of endpointGroups) {
for (const endpoint of group.endpoints) {
const method = group.prefix + (endpoint.name || '')
MovieDb.prototype[method] = async function (params: string|RequestParams = {}, options: RequestOptions = {}) {
// Implementation...
}
}
}
然后在src/endpoints/methods/configuration.ts
import {
HttpMethod,
EndpointGroup,
Response,
RequestOptions
} from '../../types'
const Configuration: EndpointGroup = {
prefix: 'configuration',
endpoints: [
{
path: 'configuration',
verb: HttpMethod.Get
}
]
}
interface ConfigurationResponse extends Response {
change_keys: Array<string>
images: {
base_url?: string
secure_base_url?: string
backdrop_sizes?: Array<string>
logo_sizes?: Array<string>
poster_sizes?: Array<string>
profile_sizes?: Array<string>
still_sizes?: Array<string>
}
}
// Module augmentation
declare module '../../moviedb' {
interface MovieDb {
configuration(options?: RequestOptions): Promise<ConfigurationResponse>
}
}
export default Configuration
当 ts 编译时,我不确定定义文件应该看起来如何(例如,增强应该与基础MovieDb
类定义合并吗?)。我可以configuration
在类的实例上调用该方法MovieDb
,但 VS Code 无法选择自动完成/类型。
是否过于模糊而无法检测?我是 Typescript 的新手,任何建议将不胜感激。
更新 1
我发现,如果我将增强功能移入其中,src/endpoints/index.ts
我将同时获得功能和智能感知。不过,我无法解释为什么。
import { MovieDb } from '../moviedb'
import Configuration from './methods/configuration'
import { RequestParams, RequestOptions } from '../types'
const endpointGroups = [
Configuration,
]
// Augmentation moved here and removed from src/endpoints/methods/configuration
interface ConfigurationResponse extends Response {
change_keys: Array<string>
images: {
base_url?: string
secure_base_url?: string
backdrop_sizes?: Array<string>
logo_sizes?: Array<string>
poster_sizes?: Array<string>
profile_sizes?: Array<string>
still_sizes?: Array<string>
}
}
declare module '../moviedb' {
interface MovieDb {
configuration(options?: RequestOptions): Promise<ConfigurationResponse>
}
}
// Create the dynamic api methods
for (const group of endpointGroups) {
for (const endpoint of group.endpoints) {
const method = group.prefix + (endpoint.name || '')
MovieDb.prototype[method] = async function (params: string|RequestParams = {}, options: RequestOptions = {}) {
console.log(`calling ${method}`, params)
return this.makeRequest(endpoint.verb, endpoint.path, params, options)
}
}
}
解决方案
推荐阅读
- botframework - 如何开始:将 Microsoft bot 框架功能嵌入到具有拖放配置功能的应用程序中?
- reactjs - 创建 React App:安装时未创建 src 和公用文件夹
- regex - 在大数据框中搜索和替换非数字数据的最佳方法
- sql-server - 什么数据类型对应于 Oracle 18C 中的 TIME(在 SQL Server 中)?
- mongodb - 如何将数据推送到数组mongodb
- python - Python 脚本中的未知语法会带来索引错误。你能读一下吗?(并解释一下?)
- android - RecyclerView 不更新
- keyboard - Ctrl + Z 键盘快捷键通常如何实际工作?
- android - 创建 2 个自定义视图时,Android 自定义视图上的 onTouchEvent 不起作用
- python - 如何使用 pytest-mock 指定模拟函数的返回值?