#typescript
#typescript
Вопрос:
Следующий блок кода допустим в TypeScript, но не в Flow:
var o = {
x: 1,
foo() { this.x = 'a'; }
};
o.foo();
Я могу вызвать сбой, если создам интерфейс для объекта:
interface Obj {
x: number;
foo(this: Obj): void;
}
var o = {
x: 1,
foo(this: Obj) { this.x = 'a'; }
};
o.foo();
Есть ли опция компиляции TypeScript, чтобы заставить его работать как Flow? (т. Е. Не нужен интерфейс)
Комментарии:
1. Как у вас может быть параметр с именем
this
?2. Это единственный известный мне способ для TypeScript проверить тип ‘this’. Смотрите typescriptlang.org/docs/handbook/functions.html и выполните поиск по «этим параметрам»
3. Я бы не ожидал этого, внешний тип не был полностью определен в контексте этой функции. Но вам не обязательно определять интерфейс для этого, вы могли бы просто использовать обычный литерал типа объекта, добавляя свойства по мере их использования.
Ответ №1:
Он определяет тип для o
в конечном счете, он просто не может этого сделать, пока o не будет полностью инициализирован. В этом примере это выдает желаемую ошибку только для второго назначения:
var o = {
x: 1,
foo() { this.x = 'a'; }
};
o.x = 'b';
z.ts (7,1): ошибка TS2322: тип ‘string’ не может быть присвоен типу
‘число’.
Если вы попытаетесь быть явным и использовать typeof o
for this
type, результат будет неожиданным:
var o = {
x: 1,
foo(this: typeof o) { this.x = 'a'; }
};
o.x = 'b';
Ошибок нет. Но почему? Для пояснения попробуйте скомпилировать тот же код с помощью —noImplicitAny:
z.ts (1,5): ошибка TS7022: ‘o’ неявно имеет тип ‘any’, потому что у него нет аннотации типа и на него прямо или косвенно ссылаются в его собственном инициализаторе.
Итак, я усугубил ситуацию, «прямо или косвенно сославшись на него в его собственном инициализаторе».
Кажется, единственный способ обойти это — определить foo
функцию вне o
объекта. К счастью, typescript поддерживает ссылки typeof o
перед o
определением:
function foo(this: typeof o) { this.x = 'a'; }
var o = {
x: 1,
foo: foo
};
o.foo();
t.ts (1,32): ошибка TS2322: Тип ‘string’ не может быть присвоен типу
‘число’.