跳过未使用参数的类型检查

问题描述 投票:0回答:4

当我编译打字稿项目时,我使用

noImplicitAny
选项,这样我就不会忘记指定变量和参数的类型。

然而有时你有一些你不使用的参数。例如:

jQuery.ajaxTransport("+*", function (options: JQueryAjaxSettings) {
  return {
    abort: function (_, callback: JQueryCallback) { 

我对 abort 函数的第一个参数不感兴趣,所以我通过将其命名为 _ 来忽略它。

这是在 TypeScript 中执行此操作的正确方法吗?我在指南中找不到它。我怀疑这不是正确的方法,因为我只能命名一个参数 _.

Typescript 引发以下错误:

错误 TS7006:参数“_”隐式具有“any”类型。

我可以只输入

_:any
,但这对于我不使用的参数来说似乎有点过分了。

typescript unused-variables
4个回答
53
投票

我也遇到了同样的问题。 使用 express 和路由,您通常只需要 res 参数。

router.get('/', function (req, res) { res.end('Bye.'); });

你使用 _ 的想法在这里有效,但我也发现这样做也有效。

function (_1, _2, _3, onlyThis) { console.log(onlyThis); }

这看起来更好,因为只做“_”我认为可能会使使用lodash/下划线有点混乱,而且它也使得它显然是你感兴趣的第四个参数。

更新:自从我发布这个答案以来已经很长时间了,并且在 评论 我收到了一些错误的想法。 所以虽然我会 澄清一下。

使用下划线技巧在 Typescript 中仍然非常有用。 就像我在原来的答案中提到的那样,如果您使用 Express 并做了

app.get('/', (req, res) => {
,您会收到警告
'req' is declared but its value is never read
,但如果您这样做 ->
app.get('/', (_req, res) => {
,警告就会消失。 无论如何,您都不应该收到
error TS7006: Parameter 'req' implicitly has an 'any' type.
错误,因为
@types/express
无论如何都应该隐式键入此参数。

更新2,。 请注意这里使用

{}
作为参数的第二个答案,可能看起来很酷,但速度相当慢,所以我个人会小心使用内部紧密循环。


35
投票

我可能会迟到,但我被其他解决方案困住了,而这个解决方案对我来说一直有效:

function ({}={}, {}={}, {}={}, onlyThis) { console.log(onlyThis); }

比较

当使用

_0
,
_1
, ... 解决方案时,我在挖掘函数方面遇到了困难,例如:

function parent(_0, _1, _2) {
  function child(_0, _1, _2) {
    // TypeScript crying about shadowed variables
  }
}

但是对于空对象它效果很好:

function parent({}, {}, {}) {
  function child({}, {}, {}) {
    // :-)
  }
}

即使参数输入如下:

function parent({}: number, {}: string, {}: any) {
  function child({}: number, {}: string, {}: any) {
    // :-) x2
  }
}

编辑:

正如here所写,如果给定参数是

undefined
null
,设置默认值可以避免抛出错误。

function parent({}={}, {}={}, {}={}) {
  function child({}={}, {}={}, {}={}) {
    // :-)
  }
}

5
投票

这绝对是邪恶的,但你可以使用这个:

function fn(...[,,,param]){
  console.log(param)
}
fn(2,3,4,5) //prints(5)

0
投票

当我将纯粹的基于 JavaScript 正则表达式的语言解析器迁移到 TypeScript 时,即使在深度嵌套的回调场景中,跳过变量同时保持事物的合理性也让我很恼火。

就我而言,经过多次挫折后,我选择从非常烦人的不类型友好的 TypeScript 正则表达式语法中手动提取变量,以便将它们提供给回调函数,以更直观的方式与它们交互并实际参与正确的类型:

export type NamedReplacerFn = (
    group: Record<string, string | undefined>,
    wholeMatch: string,
    offset: number
) => string;

export type SimpleReplacerFn = (
    groups: (string | undefined)[],
    wholeMatch: string,
    offset: string
) => string;

declare global {
    interface String {
        // Breaks down the normal string.replace method to insert the named capture groups
        // as the first parameter. This allows easy object destructuring within parameters.
        replaceNamed: (regExp: RegExp, replacerFn: NamedReplacerFn) => string;

        //Places the capture groups into an array, which helps to enforce type safety rather than using 'any[]'.
        replaceArray: (regExp: RegExp, replacerFn: SimpleReplacerFn) => string;
    }
}

String.prototype.replaceArray = function (regExp, replacerFn) {
    return this.replace(regExp, (...args) => {
        console.log(regExp, 'replacer args: ', ...args);
        return replacerFn(args.slice(1, -2), args[0], args.at(-2));
    });
};

String.prototype.replaceNamed = function (regExp, replacerFn) {
    return this.replace(regExp, (...args) =>
        replacerFn(args.at(-1), args[0], args.at(-3))
    );
};

您可以对任何函数执行类似的操作,并相应地重写参数传递给回调的方式,使您的回调保持干净和精简,并将丑陋的东西隐藏在代码库的一个令人毛骨悚然的角落。

© www.soinside.com 2019 - 2024. All rights reserved.