#typescript
#typescript
Вопрос:
Возьмите функцию с двумя перегрузками сигнатур:
type f64 = number;
function add(): f64;
function add(x: f64, y: f64): f64;
function add(x?: f64, y?: f64): f64 {
return typeof x === "number"
? x y
: 0;
}
Для пояснения, приведенный выше код завершается ошибкой при попытке добавления, что y
потенциально undefined
возможно.
Но, если x
это число, то, по расширению, параметр также y
должен быть числом, поскольку нет перегрузок, которые позволяют x
быть числом, не будучи y
также числом.
Могу ли я заставить TSC сделать вывод / понять это без избыточной двойной проверки: typeof x === "number" amp;amp; typeof y === "number"
?
Обратите внимание, что на самом деле попытка вызвать его подобным образом недопустима:
add(1, undefined);
Сбой с:
Аргумент типа ‘undefined’ нельзя присвоить параметру типа ‘number’.(2345)
Вызов был бы успешным для этой реализации, но сигнатуры перегрузок реализации не видны извне.
У меня был класс с двумя перегрузками, первый не принимал никаких параметров, другой принимал два параметра разных типов. Изначально он был написан на JS, но для его преобразования в TS потребуется реструктуризация или дополнительные утверждения, которые, я считаю, не нужны.
С сайта TS:
Типы предоставляют способ описания формы объекта, предоставляя лучшую документацию и позволяя TypeScript проверять правильность работы вашего кода.
Это код, который всегда будет работать правильно, при условии, что он вызывается через одну из перегрузок подписи, что TSC должен гарантировать.
Изменение реализации уже работающего кода в соответствии с TS исключено из таблицы.
Обновление, самое близкое, что я получил, это:
function add<T extends f64 | undefined>(x: T, y: T extends f64 ? f64 : never): f64 {
return typeof x === "number"
? x y
: 0;
}
add(1, 2); // okay
add(); // expected 2 params
add(undefined); // must be (undefined, never)
Комментарии:
1.
x?: number
означаетx
необязательный параметр типаnumber | undefined
.2. @AluanHaddad В этом нет ничего нового для меня. Есть ли что-нибудь, что подразумевало иное? Есть ли у вас лучшее решение для этого, чем опубликованное в настоящее время?
3. Я хочу сказать, что тип
x
ничего не говорит о наличииy
4. @AluanHaddad
f64?
используется только для соблюдения перегрузок, есть ли другой способ сделать это? Может быть, универсальные и троичные файлы?5. Возможно
return x ?? 0 y ?? 0
. Я согласен, что это досадная проблема, потому что мне не нравится изменять логику реализации только для удовлетворения типов
Ответ №1:
Первый подход
type f64 = number;
function add(...args: []): f64
function add(...args: [x: number, y: number]): f64
function add(...args: [x: number, y: number] | []): f64 {
if (args.length === 2) {
const [x, y] = args;
return x y
}
if (args.length === 1) { } // expected error
return 0
}
const result = add() // ok
const result1 = add(1) // expected error
const result2 = add(1, 2) // ok
const result3 = add(1, 2, 3) // expected error
Второй подход
type f64 = number;
function add(): f64;
function add(x: f64, y: f64): f64;
function add(x?: f64, y?: f64): f64 {
return x amp;amp; y
? x y
: 0;
}
const result = add() // ok
const result1 = add(1) // error
const result2 = add(1, 2) // ok
const result3 = add(1,undefined) // error
const result4 = add(0,0) // ok
Третий подход
declare const memory: ArrayBuffer;
declare function allocate(): number;
class UintArr extends Uint8Array {
constructor(); // overload 1
constructor( // overload 2
buffer: ArrayBuffer,
byteOffset: number
);
constructor(
buffer?: ArrayBuffer,
byteOffset?: number
) {
const ptr = buffer === memory // just add |undefined or remove explicit types at all
? byteOffset // overload 1
: allocate(); // overload 2
super(memory, ptr, 16);
}
};
Комментарии:
1. Я обновлю сообщение прямо сейчас, но add(0, 0) будет ошибкой для вашего второго метода, не так ли?