Ответ 1
Возвращаемая функция имеет сигнатуру вызова, но вы сказали Typescript полностью игнорировать это, добавив : any
в свою подпись.
Не делай этого.
Я новичок в typescript, и у меня есть два класса. В родительском классе я:
abstract class Component {
public deps: any = {};
public props: any = {};
public setProp(prop: string): any {
return <T>(val: T): T => {
this.props[prop] = val;
return val;
};
}
}
В дочернем классе я:
class Post extends Component {
public toggleBody: string;
constructor() {
this.toggleBody = this.setProp('showFullBody');
}
public showMore(): boolean {
return this.toggleBody(true);
}
public showLess(): boolean {
return this.toggleBody(false);
}
}
Оба showMore и ShowLess дают мне ошибку: "Невозможно вызвать выражение, тип которого не имеет сигнатуры вызова".
Но функция, которую setProp возвращает DOES, имеет подпись вызова, я думаю? Я думаю, что я неправильно понимаю что-то важное о типизации функций, но я не знаю, что это такое.
Спасибо!
Возвращаемая функция имеет сигнатуру вызова, но вы сказали Typescript полностью игнорировать это, добавив : any
в свою подпись.
Не делай этого.
"Невозможно вызвать выражение, тип которого не имеет сигнатуры вызова."
В вашем коде:
class Post extends Component {
public toggleBody: string;
constructor() {
this.toggleBody = this.setProp('showFullBody');
}
public showMore(): boolean {
return this.toggleBody(true);
}
public showLess(): boolean {
return this.toggleBody(false);
}
}
У вас есть public toggleBody: string;
. Вы не можете вызвать string
как функцию. Следовательно, ошибки на: this.toggleBody(true);
и this.toggleBody(false);
Давайте разберемся с этим:
Ошибка говорит
Невозможно вызвать выражение, тип которого не имеет подписи вызова.
Код:
Проблема в этой строке public toggleBody: string;
&
Это отношение к этим строкам:
...
return this.toggleBody(true);
...
return this.toggleBody(false);
Ваше высказывание toggleBody
- это string
но затем вы рассматриваете ее как нечто, имеющее call signature
(т.е. Структуру чего-то, что может быть вызвано: лямбда-выражения, proc, функции, методы и т.д. В JS просто функция tho.). Вам нужно изменить объявление на public toggleBody: (arg: boolean) => boolean;
,
Дополнительные детали:
"вызвать" означает ваш вызов или применение функции.
"Выражение" в Javascript - это то, что создает значение, поэтому this.toggleBody()
считается выражением.
"тип" объявлен в этой строке public toggleBody: string
"отсутствует подпись вызова" это происходит потому, что вы пытаетесь вызвать что-то this.toggleBody()
, у которого нет подписи (то есть структура чего-то, что может быть вызвано: лямбда-выражения, процедуры, функции, методы и т.д.), которые могут быть называется. Вы сказали, что this.toggleBody
действует как строка.
Другими словами, ошибка говорит
Невозможно вызвать выражение (this.toggleBody), поскольку у его типа (: string) отсутствует подпись вызова (bc имеет строковую подпись.)
Я думаю, что вы хотите:
abstract class Component {
public deps: any = {};
public props: any = {};
public makePropSetter<T>(prop: string): (val: T) => T {
return function(val) {
this.props[prop] = val
return val
}
}
}
class Post extends Component {
public toggleBody: (val: boolean) => boolean;
constructor () {
super()
this.toggleBody = this.makePropSetter<boolean>('showFullBody')
}
showMore (): boolean {
return this.toggleBody(true)
}
showLess (): boolean {
return this.toggleBody(false)
}
}
Важное изменение в setProp
(т.е. makePropSetter
в новом коде). То, что вы действительно делаете, это сказать: это функция, которая снабжается именем свойства, возвратит функцию, которая позволит вам изменить это свойство.
<T>
на makePropSetter
позволяет заблокировать эту функцию до определенного типа. <boolean>
в конструкторе подкласса фактически необязателен. Поскольку вы назначаете toggleBody
, и этот тип уже полностью задан, компилятор TS сможет самостоятельно его выполнить.
Затем в вашем подклассе вы вызываете эту функцию, а тип возврата теперь правильно понимается как функция с определенной сигнатурой. Естественно, вам понадобится toggleBody
уважать ту же подпись.
Это означает, что вы пытаетесь вызвать что-то, что не является функцией
const foo = 'string'
foo() // error
Это всего лишь пример ошибки, но в несколько ином контексте, где ничего не возвращалось, и машинописный код ожидал объект, похожий на обещание.
Используя машинопись и реагирование, ошибка произошла для меня с:
let thing = SomePromise.then(Promise.resolve)
.catch(e => {
this.setState(e)
// not returning anything here
})
// thing.then().catch()
Мне нужно было вернуть объект обещания:
let thing = SomePromise.then(Promise.resolve)
.catch(Promise.reject)
// thing.then().catch()
Добавьте тип в вашу переменную и затем вернитесь.
Например:
const myVariable : string [] = ['hello', 'there'];
const result = myVaraible.map(x=> {
return
{
x.id
}
});
=> Важной частью является добавление строки [] и т.д.
У меня было то же сообщение об ошибке. В моем случае я случайно смешал синтаксис ES6 export default function myFunc
с const myFunc = require('./myFunc');
.
Использование module.exports = myFunc;
вместо этого решило проблему.
Эта ошибка может быть вызвана тем, что вы запрашиваете значение у чего-либо и ставите круглые скобки в конце, как если бы это был вызов функции, но значение корректно извлекается без использования круглых скобок. Например, если то, к чему вы обращаетесь, это свойство 'get' в Typescript.
private IMadeAMistakeHere(): void {
let mynumber = this.SuperCoolNumber();
}
private IDidItCorrectly(): void {
let mynumber = this.SuperCoolNumber;
}
private get SuperCoolNumber(): number {
let response = 42;
return response;
};