Как удалить name
из функции следующего типа:
type Func = {
(): number
name: string
}
Omit<Func, 'name'>
приведет к never
.
Как удалить name
из функции следующего типа:
type Func = {
(): number
name: string
}
Omit<Func, 'name'>
приведет к never
.
Вы не можете этого сделать, потому что name
является частью специального встроенного Function
интерфейса, от которого наследуются все вызываемые объекты в TypeScript. Как только компилятор видит, что тип вызывается, он будет иметь name
(и bind
, и call
, и apply
, и т. Д.). Вы не сможете расширить тип, чтобы удалить эти ключи.
См. microsoft / TypeScript # 27575 для канонической проблемы по этому поводу. Я не знаю, что там что-то случится, но вы должны пойти туда, чтобы описать свой вариант использования и поставить отметку, если вы хотите повысить вероятность того, что проблема будет решена.
В любом случае, самое близкое, что вы сможете здесь получить, - это иметь name
типа never
, что является сужением, а не расширением:
type MyFunc = {
(): number;
readonly name: never;
};
Вы все еще можете назвать это:
declare const f: MyFunc;
const num = f(); // okay
И хотя он имеет name
:
f.name; // no error here, but
Этот name
больше не рассматривается как пригодный для использования string
тип:
f.name.toUpperCase(); // error
// Property 'toUpperCase' does not exist on type 'never'.
Если вы говорили о другом свойстве, которое не встроено в Function
, например
type MyFuncTwo = {
(): number;
title: string;
age: number;
}
тогда вы можете удалить их, но не с помощью Omit<>
, который является отображаемым типом. Сопоставленные типы пропускают сигнатуры вызова / построения. Для этого тоже есть открытая проблема: microsoft / TypeScript # 29261. Чтобы обойти это, вам нужно будет создать свой собственный сопоставитель типов, который повторно добавляет сигнатуру вызова:
type MyOmit<T, K extends PropertyKey> =
(T extends (...args: infer A) => infer R ? (...args: A) => R : unknown) & Omit<T, K>;
Это работает для приведенного выше примера:
type MyFuncThree = MyOmit<MyFuncTwo, "title">;
// type MyFuncThree = (() => number) & Pick<MyFuncTwo, "age">
но есть всевозможные крайние случаи, связанные с перегрузками и, возможно, дженериками. Если вы действительно хотите увидеть обходной путь, вы можете перейти на # 29261, поставить ему ???? и описать свой вариант использования.
name
(независимо от того, сообщаете ли вы об этом TypeScript), если только вы не играете в игры, чтобы избавиться от него, но проблема не в этом.) - person T.J. Crowder   schedule 21.09.2020keyof
вOmit
не поймает подпись вызова. Самым простым решением, вероятно, является создание двух различных типов - одного для функции и одного для объекта, которые затем пересекаются. Или вы извлекаете подпись - посмотрите: - person ford04   schedule 21.09.2020