【问题标题】:Typescript declaration打字稿声明
【发布时间】:2021-04-01 20:54:43
【问题描述】:

我目前正在学习 Typescript 声明,但我坚持将不同数量的参数传递给函数的概念。

换句话说,我如何为这样的 JavaScript 函数进行 Typescript 声明:

// Formats a string with the supplied parameter(s)
// Examples Usage: 
//  formatString("User {0} logged in", 'John');
//  formatString("Max {0} words allowed", 128.8999);
//  formatString("Form {0} to {1}", [10, 100]);

const function FormatString(sTemplate, params) {
    if (typeof params != undefined && arguments.length == 2) {
        if (params.constructor != Array) {
            if (typeof params == 'string')
                params = [params];
            else
                params = [String(params)];
        }

        if (params.constructor == Array) {
            $.each(params, function (index, value) {
                if (typeof value == 'string')
                    sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), value);
                else
                    sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), String(value));
            });
        }
    }
    return sTemplate;
}

【问题讨论】:

  • 尝试将示例简化为最小问题
  • 请考虑修改此问题中的代码以构成minimal reproducible example,将其放入像The TypeScript Playground 这样的独立IDE 中时,可以清楚地说明您面临的问题。这将使那些想要帮助您的人立即着手解决问题,而无需首先重新创建它。它将使您得到的任何答案都可以针对定义明确的用例进行测试。 $ 是什么? const function 是什么?你能描述一下你真正打算接受的params吗?它可以是任何东西吗?等等。

标签: javascript typescript declaration


【解决方案1】:

一些提示:

  1. 在 JavaScript/TypeScript 中,当要表示严格相等或不相等时,不要使用 ==!=;改为使用===!==,否则语言perfoms a looser comparison(例如4 == '4'true,而4 === '4'false)。
  2. 要检查某个东西是否是Array,更惯用的解决方案是Array.isArray(obj)
  3. 尽量避免使用arguments。它被认为是不好的做法,在实践中已被弃用,有时根本无法访问。使用rest 参数通常更好(更安全、更容易)使用。
  4. 要将number 转换为string,首选.toString() 方法,这可以确保它实际上是一个正确的值和errors when empty
  5. 无需使用$ 或任何花哨的依赖项,例如each()array.forEach() 现在应该在浏览器中得到很好的支持。

综上所述,有意见重写您的代码将是:

const formatString = (sTemplate: string, ...params: Array<string | number>) => {
    params.forEach((value, index) => {
        const newValue = typeof value === 'string' ? value : value.toString(10);
        sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), newValue);
    });
    return sTemplate;
};

formatString("User {0} logged in", 'John');
formatString("Max {0} words allowed", 128.8999);
formatString("Form {0} to {1}", 10, 100);

注意额外的params 被允许,而不是一个数组。虽然您可以实现您在消息中的内容(单个参数或一组参数),但我认为这有点不习惯并且可能会引起混淆。

在我上面的例子中,你可以仍然通过使用这样的数组展开来传递一个数组作为参数(比如说,它是在其他地方生成的):

const nums = [10, 100];
formatString("Form {0} to {1}", ...nums);

但是,如果您想保留原始语法,可以这样使用它:

const formatString = (sTemplate: string, params?: Array<string | number> | string | number) => {
    if (params !== undefined) {
        const newParams = Array.isArray(params) ? params : [params];
        newParams.forEach((value, index) => {
            const newValue = typeof value === 'string' ? value : value.toString(10);
            sTemplate = sTemplate.replace(new RegExp("\\{" + index + "\\}", "g"), newValue);
        });
    }
    return sTemplate;
};

formatString("User {0} logged in", 'John');
formatString("Max {0} words allowed", 128.8999);
formatString("Form {0} to {1}", [10, 100]);
formatString("No params");

但另外一个警告是,如果 undefined 是单个参数,则不能将其用作实际参数;它会假设它不存在并且不在模板中执行替换。

祝你学习之旅好运! JavaScript 是一种有一些问题的语言,例如上面提到的 ==/!= 案例,但 TypeScript 确实更容易获得有效、安全的代码,所以我建议继续走这条路!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2017-09-12
    • 2021-02-06
    • 2017-02-16
    • 2018-11-06
    相关资源
    最近更新 更多