lib 更新请求
我的代码中存在缺少只读修饰符的类型检查问题。例如,以下代码无法进行类型检查:
declare const vals: readonly number[]
Math.max.apply(null, vals)
^^^^
Argument of type 'readonly number[]' is not
assignable to parameter of type 'number[]'
Playground 链接
这是由于以下签名导致的:
interface Math {
max(...values: number[]): number
}
interface CallableFunction extends Function {
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R
}
这些签名应该被替换为:
interface Math {
max(...values: readonly number[]): number
}
interface CallableFunction extends Function {
apply<T, A extends readonly any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R
}
Playground 链接
基本上,每个数组剩余参数都应该是只读的,并且库中还有其他需要添加只读的地方。我已经在 fork 上进行了这些更改(请查看该分支的最后一次提交)。我不确定接下来该如何进行。有很多更改需要执行。也许这些更改应该分成几个部分进行?
请注意,如果 TypeScript 能够隐式地将数组剩余参数处理为只读(无论 readonly 修饰符是否存在),那么可以避免很多更改。我不认为有可变数组剩余参数的价值。然而,这会给类型检查器带来一个特殊情况,我个人并不特别喜欢这种情况。
4条答案
按热度按时间vof42yt11#
然而,这在类型检查器中添加了一个特殊情况,我个人并不特别喜欢这种做法。我不一定非要称之为“特殊情况”。剩余参数是一种语法构造,许多其他语法构造也会改变事物的类型。
实际上,这甚至可以做到保持变量的内部类型不变,但将函数的剩余参数用
Readonly
Package 起来。例如:von4xj4u2#
我不认为需要重写任何休息参数(例如在 $x_{
Math.max
}$ 中)。最多,你需要将任何 捕获的 参数列表类型 $x_{A
}$ 重写为 $x_{readonly [...A]
}$,对吧?所以我们可以交换 $x_{args
}$ 的类型。$x_{
}$
laximzn53#
这是允许的:
这很有道理,因为扩展数组总是会创建一个副本。所以问题仅限于
func.apply()
。yx2lnoni4#
我认为没有必要重写任何休息参数(例如在
Math.max
中)。最多,你需要将任何 捕获的 参数列表类型A
重写为readonly [...A]
,对吗?所以我们可以切换args
这绝对是一个更好的建议。