【问题标题】:Dynamically access an imported module's methods in TypeScript在 TypeScript 中动态访问导入模块的方法
【发布时间】:2019-12-04 01:31:31
【问题描述】:

我正在尝试做这样的事情:

import * as d3 from 'd3-scale-chromatic'

const selectColor = (
    decimal: number, 
    colorScheme: string = 'interpolateRainbow'
): string => 
    d3[colorScheme](decimal)

但我收到了这个 TS 错误:

元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引类型“typeof import("PATH_TO_MODULES/node_modules/@types/d3-scale-chromatic")”

认为我基本上想用以下方式扩展我正在导入的类型:

interface d3 {
    [key: string]: (number) => string
}

【问题讨论】:

    标签: d3.js typescript-typings typescript2.0 typescript-generics


    【解决方案1】:

    方法一:将colorScheme声明为keyof typeof d3,在调用处将字符串类型转换为它。

    type D3Scale = keyof typeof d3;
    const selectColor = (
        decimal: number, 
        colorScheme: D3Scale = 'interpolateRainbow'
    ): string => 
        d3[colorScheme](decimal);
    
    selectColor(1,'interpolateRainbow'); // OK
    let k:string = prompt("Input method name:");
    selectColor(1,k as D3Scale); // need to cast
    

    方法 2:将 d3 转换为其索引签名。

    type D3IndexType = {[k:string]:typeof d3[keyof typeof d3]};
    const selectColor = (
        decimal: number, 
        colorScheme: string = 'interpolateRainbow'
    ): string => 
        (d3 as D3IndexType)[colorScheme](decimal)
    

    【讨论】:

    • 我在我的案例中使用了方法 2 - 效果很好。谢谢!
    【解决方案2】:

    您可以玩转Conditional types 并将每个 colorScheme 映射到它的实现。

    https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types

    【讨论】:

    • 但是没有理由这样做。如果有些东西很难在打字稿上写出来,你很可能做错了。我会说您正在尝试将静态类型函数合并到运行时定义的“selectColor”函数,然后再次使其成为静态类型。您可以使用条件类型来做到这一点,但我没有看到做额外工作的好处
    猜你喜欢
    • 2020-07-21
    • 2013-08-09
    • 2019-02-27
    • 1970-01-01
    • 2015-12-27
    • 2020-06-06
    • 2011-11-09
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多