【问题标题】:Dynamically importing Typescript file as an alternative to json-based config动态导入 Typescript 文件作为基于 json 的配置的替代方案
【发布时间】:2020-07-02 23:41:09
【问题描述】:

这是背景: 我们正在使用 Typescript 开发 AWS CDK 模块(仅供参考,我在 TS 方面不是很有经验)。

例如,将有一个模块用于表示基于容器的应用程序,开发人员可以使用它来配置他们的服务。非常高级,每个应用程序的“定义”将类似于(非常高级):

import {containerApp} from 'CompanyContainerApp'
const environment = callSomeMethodToFindEnv() // for example, 'prod'
config = import('/prod')
const myApp = new containerApp(`myapp-${environment}`, config)

所以这里的挑战是'prod'和'dev'代表不同的配置值,需要发送到containerApp的构造函数。我当然可以使用简单的 json 文件并解析它们,但是这些配置可能很复杂,将它们放在一个类型中可以更容易地表达哪些配置属性是必需的,哪些是可选的等等。

现在这是我的代码:

// cat index.ts
import {Config} from './configdefinition'

export function hello(word: string = world): string {
    const envName = 'prod'
    const config: Config = import(`./${envName}`)
    return `Hello2 ${world}! `
}
hello()


// cat configdefinition.ts
export class Config {
    // props with defaults
    readonly numberOfLegs: number = 8
    constructor(
        // required props
        readonly name: string,
        readonly lastname?: string
    ) {}
}


// cat prod.ts
import {Config} from './configdefinition'
const config = new Config(
    'prodman',
    'wakka'
)
export default config

Typescript 抱怨说 'config' 是一个“承诺”,而不是 Config 类的实例。 我知道这是一个悬而未决的问题,但我想我想弄清楚这是否可能,或者我是否应该坚持使用老式 json 进行配置(这将是一种耻辱,但它不会杀了我们)。

就目前而言,ts 抱怨我的 config const 确实是一个承诺,而不是 Confgclass 的实例 - 看起来使用 import 函数会让我陷入不得不处理承诺等,我希望避免这种情况。

所以我想这是一个开放式问题,但总结一下: 1. 我应该放弃并改用基于 json 的配置吗 2. 如果不是,动态导入另一个类实例的正确方法是什么,同时仍保持“强”类型? (例如,要知道config 对象是Config 的一个实例)

非常感谢任何指针,我相当对 Typescript 很陌生。

更新:一个回复直接发送给我,我现在正在探索使用 Promise。到目前为止,这是我想出的:

// cat configdefinition
export class Config {
    // props with defaults
    readonly numberOfLegs: number = 8
    constructor(
        // required props
        readonly name: string,
        readonly lastname?: string
    ) {}
}


// cat prod.ts
import {Config} from './configdefinition'
export const config: Config = new Config('Bobba', 'Fett')

//cat index.ts
import {Config} from './configdefinition'

export function doSomeStuff(config: any) {
    // @ts-ignore
    const thisConfig: Config = config.config
    console.log(thisConfig.lastname)
}

export function hello() {
    const envName = 'prod'
    const configImport: Promise<Config> = import(`./${envName}`)
    configImport.then(
        result => doSomeStuff(result)
    )
}
hello()

因此,我必须在“强​​制”打字稿中添加一个 ts-ignore 以动态提取动态导入的 configattribute。我怀疑有一些方法可以做到这一点,不需要这种违反规则的行为,但就目前而言,我对此感到满意。希望这对将来的人有所帮助。

【问题讨论】:

    标签: typescript aws-cdk


    【解决方案1】:

    以下内容对我有用:

    刚刚修改:

    const config: Promise<Config> = import(`./${envName}`)
    

    一个模块中的完整工作代码:

    function hello(word: string = 'world'): string {
        const envName = 'prod'
        const config: Promise<Config> = import(`./${envName}`)
        return `Hello2 ${word}! `
    }
    console.log(hello());
    
    
    // cat configdefinition.ts
     class Config {
        // props with defaults
        readonly numberOfLegs: number = 8
        constructor(
            // required props
            readonly name: string,
            readonly lastname?: string
        ) {}
    }
    
    
    // cat prod.ts
    
    const config = new Config(
        'prodman',
        'wakka'
    );
    

    或者更好地使用异步等待函数,例如:

    async function hello(word: string = 'world'): Promise<string> {
      const envName = 'prod'
      const config: Config = await import(`./${envName}`)
      return `Hello2 ${word}! `
    }
    console.log(hello());
    

    【讨论】:

    • 感谢您的回复!简单地切换到Promise&lt;Config&gt; 似乎并不能解决这个承诺,它只是在我记录它时输出&lt;pending&gt;。我希望避免做异步,我什至不确定我使用的 cdk 工具是否支持它。但如果这是一个选项,我会明确地研究。您的异步示例完美运行。谢谢!
    • 是的,因为这是一个承诺.. 使用 config.then(result => console.log),或者更好的异步等待方式...
    • 不错。这为我指明了正确的方向,更新了我的答案。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多