我試圖在打字稿的多載函式中呼叫另一個多載函式。由于 typeFunc2與type相同Func1,因此可以肯定傳遞給func1from 的引數func2將被正確鍵入。然而,打字稿似乎無法接受,并拋出錯誤。
type Func1 = {
(a: string, b: string): void
(a: undefined, b: undefined): void
}
const func1: Func1 = (a, b) => {
console.log(a, b)
}
type Func2 = {
(a: string, b: string): void
(a: undefined, b: undefined): void
}
const func2: Func2 = (a, b) => {
func1(a, b)
console.log(a, b)
}
/*
No overload matches this call.
Overload 1 of 2, '(a: string, b: string): void', gave the following error.
Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
Overload 2 of 2, '(a: undefined, b: undefined): void', gave the following error.
Argument of type 'string | undefined' is not assignable to parameter of type 'undefined'.
Type 'string' is not assignable to type 'undefined'.
*/
我該如何解決這個問題?
編輯:這是我嘗試的實際實作:
type ParseRandomArgs = {
(a: undefined, b: undefined): [number, number]
(a: number, b: undefined): [number, number]
(a: number, b: number): [number, number]
(a: [number, number], b: undefined): [number, number]
(a: [number], b: undefined): [number, number]
}
type RandomNumber = {
(a: undefined, b: undefined): number
(a: number, b: undefined): number
(a: number, b: number): number
(a: [number, number], b: undefined): number
(a: [number], b: undefined): number
}
const isNullish = (value: any) => value === undefined || value === null
const parseRandomArgs: ParseRandomArgs = (a, b) => {
if (Array.isArray(a)) {
if (a.length === 2) return a
return [0, a[0]]
}
else if (isNullish(b)) return [0, isNullish(a) ? 1 : a as number]
else return [a as number, b as number]
}
const randomFloat: RandomNumber = (a, b) => {
let [min, max] = parseRandomArgs(a, b) // [min, max]
return Math.random() * (max - min) min
}
const randomInt: RandomNumber = (a, b) => {
let [min, max] = parseRandomArgs(a, b) // [min, max]
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min) min)
}
uj5u.com熱心網友回復:
正如@Mike 所提到的,使undefined引數可選使多載更容易解決。這應該有效:
type RandomGenerator = {
(start: number, end?: number): number
(range: [number, number]): number;
(range: [number]): number;
}
const randomFloat: RandomGenerator = (start, end?) => {
const [min, max] = parseRandomArgs(start, end as number | undefined);
return computeRandom(min, max);
}
const randomInt: RandomGenerator = (start, end?) => {
const [min, max] = parseRandomArgs(start, end as number | undefined);
return Math.floor(computeRandom(min, max));
}
const computeRandom = (min: number, max: number): number => {
return Math.random() * (max - min) min;
}
const parseRandomArgs = (first: number | [number, number] | [number], second: number | undefined): [number, number] => {
let args: [number, number];
if (Array.isArray(first) && first.length === 1) {
args = [0, first[0]];
} else if (Array.isArray(first) && first.length === 2) {
args = first;
} else {
args = Number.isFinite(second) ? [first, second as number] : [0, first];
}
const [min, max] = args;
return [Math.ceil(min), Math.floor(max)];
}
uj5u.com熱心網友回復:
我認為您嘗試撰寫太干凈的代碼
考慮第二個例子(使用亂數):打字稿實際上連接了所有可能的引數變體
const randomInt: RandomNumber = (a, b) => {
//a: number | [number, number] | [number] | undefined
//b: number | undefined
}
并且您的 RandomNumber/ParseRandomArgs 定義只能用于呼叫驗證
所以第一個解決方案是使用所有引數的聯合來擴展 ParseRandomArgs
type ParseRandomArgs = {
...
(a: [number]| [number, number] | number | undefined, b: number | undefined): [number, number]
}
其次,將這樣的聯合移動到受保護的函式并將 ParseRandomArgs 轉換為代理
const _parseRandomArgs = function(a: [number] | [number,number] | number | undefined ,b?: number | undefined): [number,number]{
...
}
const parseRandomArgs: ParseRandomArgs = (a, b) => {
return _parseRandomArgs(a,b);
}
const randomFloat: RandomNumber = (a, b) => {
let [min, max] = _parseRandomArgs(a, b) // [min, max]
return Math.random() * (max - min) min
}
我建議你把所有未定義的引數 - 可選

TS游樂場
type Fn<
Params extends unknown[] = any[],
Result = any,
> = (...args: Params) => Result;
type CommonParams = [
[max?: number],
[min: number, max?: number],
[minAndMax: [min: number, max: number]],
[maxOnly: [max: number]],
];
type ParseFn = Fn<CommonParams[number], [number, number]>;
type RandomFn = Fn<CommonParams[number], number>;
function isNullish <T>(value: T): value is Exclude<T, NonNullable<T>> {
return value === undefined || value === null;
}
const parseRandomArgs: ParseFn = (...args) => {
const [a, b] = args;
if (Array.isArray(a)) return a.length === 2 ? a : [0, a[0]];
if (isNullish(a)) return [0, 1];
return isNullish(b) ? [0, a] : [a, b];
};
const randomFloat: RandomFn = (...args) => {
const [min, max] = parseRandomArgs(...args);
return Math.random() * (max - min) min;
};
const randomInt: RandomFn = (...args) => {
let [min, max] = parseRandomArgs(...args);
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) min);
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/392455.html
標籤:javascript 打字稿 超载
