当我编译打字稿项目时,我使用
noImplicitAny
选项,这样我就不会忘记指定变量和参数的类型。
然而有时你有一些你不使用的参数。例如:
jQuery.ajaxTransport("+*", function (options: JQueryAjaxSettings) {
return {
abort: function (_, callback: JQueryCallback) {
我对 abort 函数的第一个参数不感兴趣,所以我通过将其命名为 _ 来忽略它。
这是在 TypeScript 中执行此操作的正确方法吗?我在指南中找不到它。我怀疑这不是正确的方法,因为我只能命名一个参数 _.
Typescript 引发以下错误:
错误 TS7006:参数“_”隐式具有“any”类型。
我可以只输入
_:any
,但这对于我不使用的参数来说似乎有点过分了。
我也遇到了同样的问题。 使用 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,。 请注意这里使用
作为参数的第二个答案,可能看起来很酷,但速度相当慢,所以我个人会小心使用内部紧密循环。{}
我可能会迟到,但我被其他解决方案困住了,而这个解决方案对我来说一直有效:
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({}={}, {}={}, {}={}) {
// :-)
}
}
这绝对是邪恶的,但你可以使用这个:
function fn(...[,,,param]){
console.log(param)
}
fn(2,3,4,5) //prints(5)
当我将纯粹的基于 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))
);
};
您可以对任何函数执行类似的操作,并相应地重写参数传递给回调的方式,使您的回调保持干净和精简,并将丑陋的东西隐藏在代码库的一个令人毛骨悚然的角落。