【问题标题】:Attempting to access compiled Handlebars templates file raises implicit any error尝试访问已编译的 Handlebars 模板文件会引发隐含的任何错误
【发布时间】:2015-05-04 15:24:34
【问题描述】:

我一直在尝试为我的前端开发工作设置一个 gulpfile,但我遇到了一些问题。大多数都很容易修复,但我不知道这里发生了什么。

我正在使用的相关内容是:

  • 打字稿
  • 车把
  • 吞咽
  • Browserify(使用 tsify)

设置(希望只有相关部分)如下:

gulpfile.js:

gulp.task('handlebars', function() {
    return gulp.src('./src/templates/**/*.hbs')
        .pipe(handlebars())
        .pipe(wrap('Handlebars.template(<%= contents %>)'))
        .pipe(declare({
            noRedeclare: true,
            namespace: "templates",
            processName: function(filePath) {
                return declare.processNameByPath(filePath.replace('templates/', ''));
            }
        }))
        .pipe(concat('hbs.js'))
        .pipe(wrap('var Handlebars = require("handlebars");\n<%= contents %>'))
        .pipe(gulp.dest('./src/templates'))
});

ma​​in.ts:

/// <reference path="../typings/hbs.d.ts" />
import hbs = require("hbs.js");

var template = hbs.templates["src"]["index"];

hbs.d.ts:

declare module "hbs.js" {
    export var templates: {
        [index: string]: (model: any) => string;
    }
}

我从 gulp-handlebars readme 和 hbs.d.ts 借用了 gulp 任务从 StackOverflow answer。到现在为止还挺好。 gulp 输出的templates.js 文件长这样:

var Handlebars = require("handlebars");
this["templates"] = this["templates"] || {};
this["templates"]["src"] = this["templates"]["src"] || {};
this["templates"]["src"]["index"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    return "Hello world\n";
},"useData":true});

我做错了,因为我收到了一个错误:"TS7017: src/ts/main.ts(11,24): TS7017: 对象类型的索引签名隐含一个'any ' 类型。” 我查看了错误,但 it seems to be 我必须设置一个显式索引类型,但我的代码中的 [index: string] 不正是这样做的吗?还是整个声明都错了?

我已取消设置 noImplicitAny,因此我可以继续工作,但我喜欢这个选项并希望继续使用它。

【问题讨论】:

  • 不完全确定你想在这里做什么,但要么你使用的“模板”界面错误,要么你定义了错误的模板。请在下面查看我的答案。

标签: typescript gulp handlebars.js


【解决方案1】:

在你的例子中:

var template = templates["src"]["index"];

"var template" 会得到一个隐式的 any 类型。

一些例子:

var templates: {
    [index: string]: (model: any) => string;
}

在下面的 foo 中将有类型 (model: any) => 字符串。在这种情况下 foo 是一个函数。

var foo = templates["src"];

如果您执行以下操作,则 foo 将具有任何类型。但我不明白你为什么要这样做,你是在索引一个像数组这样的函数。

var foo2 = templates["src"]["index"];

鉴于你的“模板”界面应该是这样的,你应该做什么?

var foo3 = templates["src"]("index");

在这种情况下,foo3 的类型为 string,由“模板”接口中函数的方法返回类型给出。

如果你想以你的方式使用“模板”,问题只是界面错误:

var templates: {
    [src: string]: { [index: string]: any };
}

// template here will have type any (but not implicitly)
var template = templates["src"]["index"];

编辑: 来自gulp-handlebars 上的链接示例:

this["MyApp"] = this["MyApp"] || {};
this["MyApp"]["templates"] = this["MyApp"]["templates"] || {};
this["MyApp"]["templates"]["App"] = Handlebars.template(/* compiled template */);
this["MyApp"]["templates"]["Other"] = this["MyApp"]["templates"]["Other"] || {};
this["MyApp"]["templates"]["Other"]["item"] = Handlebars.template(/* compiled template */);
this["MyApp"]["templates"]["App"] = this["MyApp"]["templates"]["App"] || {};
this["MyApp"]["templates"]["App"]["footer"] = Handlebars.template(/* compiled template */);
this["MyApp"]["templates"]["App"]["header"] = Handlebars.template(/* compiled template */);

会导致 typescript 的声明看起来像这样:

declare var MyApp: {
    templates : {
        App: { 
            () : string;
            footer: () => string;
            header : () => string;
        }
        Other: { item: () => string };
    }
}

var app = MyApp.templates.App();
var footer = MyApp.templates.App.footer();
var item = MyApp.templates.Other.item();

【讨论】:

  • 因此,如果您查看我的最后一个代码块,您会看到编译后的 Handlebars.js 文件输出了一个任意深度的数组(例如 templates["src"]["index"] 或者它可以更深,例如 templates["src"]["index"]["base"] 等等)。这些级别中的任何一个都可以引用一个函数,但也可以像数组一样被索引。 See here.
  • 我在最后添加了一个部分,描述了你可以做些什么来在 typescript 中声明车把结构的外观。我认为没有一种简单的方法可以自动执行此操作。
  • 嗯,谢谢。我想我可以这样做...我暂时将其打开,看看是否有其他人可以想出其他方法来解决这个问题。
猜你喜欢
  • 2021-12-23
  • 1970-01-01
  • 2013-06-01
  • 2015-01-17
  • 2013-03-14
  • 2023-04-03
  • 2020-10-17
  • 1970-01-01
  • 2021-01-04
相关资源
最近更新 更多