在 TypeScript 定义文件中定义嵌套选项的最佳方式

Best way to define nested options in a TypeScript definition file

我正在编写一个 TypeScript 定义文件 .d.ts 并尝试定义这段 javascript 代码:

来自:http://summernote.org/deep-dive/#initialization-options

$('#foo').bar({
  toolbar: [
    ['style', ['bold', 'italic', 'underline', 'clear']],
    ['font', ['strikethrough', 'superscript', 'subscript']],
    ['fontsize', ['fontsize']],
    ['color', ['color']],
    ['para', ['ul', 'ol', 'paragraph']],
    ['height', ['height']],
  ],
 otheroption: // ...
});

定义这种结构(嵌套选项)的最佳方法是什么?

这是我目前找到的,但不知道推荐什么或者是否有更好的解决方案。

interface fooOptions {
  toolbar?: any
}

type toolbarOptions = [string, string[]][];
interface foo {
   toolbar?: toolbarOptions
}

type toolbarOptionNames = 'style' | 'font' | 'fontsize' | 'color' | 'para' | 'height';
type toolbarOptionValues = 'bold' | 'italic' | 'underline' | 'clear' | 'strikethrough' | 'superscript' | 'subscript' | 'fontsize' | 'color' | 'ul' | 'ol' | 'paragraph' | 'height';

interface foo {
   toolbar?: [toolbarOptionNames, toolbarOptionValues[]][];
}

type toolbarStyleGroupOptions = 'bold' | 'italic' | 'underline' | 'clear';
type toolbarFontGroupOptions = 'strikethrough' | 'superscript' | 'subscript';
type toolbarFontsizeGroupOptions = 'fontsize';
// etc...

type toolbarDef = [
    ['style', toolbarStyleGroupOptions[]]
    | ['font', toolbarFontGroupOptions[]]
    | ['fontsize', toolbarFontsizeGroupOptions[]]
    // | ...
];

interface foo {
    toolbar?: toolbarDef;
}

还是其他方式?

我认为你提出的可能是目前最好的选择。不过,您真正想要做的是能够一般地定义一些东西,对吧?你想说这是一个选项名称对列表(来自这个有效选项名称列表)+选项值(来自与前面名称对应的值)。除非你明确地将两者联系起来(如你的最后一个例子),否则我认为你不能那样做。

最后一个例子可能是目前最好的选择,这就是我要做的,尽管它会冗长得令人讨厌。

不过在短期内,会有一个更好的新选择:keyof。这有点复杂,但本质上可以让您根据另一种类型的键和对应值来定义一种类型。我认为这种情况的示例如下:

type toolbarOptionsMap = {
    'style': 'bold' | 'italic' | 'underline',
    'font': 'strikethrough' | 'superscript' | 'subscript'
    ...
}

type toolbarOption<T extends keyof toolbarOptionsMap> = [T, toolbarOptionsMap[T][]];
// keyof toolbarOptionsMap = 'style' | 'font'
// T extends keyof toolbarOptionsMap, so is one of those strings.
// toolbarOptionsMap[T] is the type of the corresponding value for T

// Then we just make a list of these
type toolbar = toolbarOption<keyof toolbarOptionsMap>[];

有了它,您只需定义一次有效的选项集,作为一个对象类型,然后将该类型转换为您正在寻找的 [option, optionValues] 对形式,而无需一遍又一遍地复制每个选项再次.

这还不是最终版本和发布版,所以我还没有实际检查过,但我非常有信心它会在上线后发挥作用。这应该出现在 TypeScript 2.1 中,它应该在 11 月底之前登陆,即本周。看这个 space!