首页 > 解决方案 > 模块扩充应该如何编译

问题描述

我理解模块扩充的概念。我可以编译一些东西,并且可以获得我想要的功能,除了我无法从我的扩充中检测到类型。这是对我正在做的事情的简化。

我有一堂课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)
    }
  }
}

标签: typescripttypescript-typings

解决方案


推荐阅读