Тип вывода
TypeScript может вывести (проверить) типы переменных в соответствии с некоторыми простыми правилами. Вы можете быстро понять их на практике.
Определение переменных
Тип переменной, выведенной из определения:
let foo = 123; // foo is a `number`
let bar = "Hello"; // bar is a `string`
foo = bar; // Error: cannot assign `string` to a `number`
Это пример типов, проходящих справа налево.
Тип возврата функции
Тип возврата может быть выведен с помощью оператора return
, как показано ниже. Функция вывода возвращает число:
function add(a: number, b: number) {
return a + b;
}
Это пример типов, протекающих снизу вверх.
Присваивание
Типы функциональных параметров/возвращаемых значений также могут быть определены по присваиванию. Как показано ниже, тип foo
- Adder
, который позволяет параметрам a
и b
в foo
иметь тип number
.
type Adder = (a: number, b: number) => number;
let foo: Adder = (a, b) => a + b;
Этот факт может быть подтвержден следующим кодом: TypeScript выдаст предупреждение об ошибке, как вы и ожидали:
type Adder = (a: number, b: number) => number;
let foo: Adder = (a, b) => {
a = 'hello'; // Error: cannot assign `string` to a `number`
return a + b;
};
Это пример типов, проходящих слева направо.
Если вы создаете функцию, а параметр функции является функцией обратного вызова, к ней применяются те же правила назначения. argument
к parameter
- это просто еще одна форма назначения переменных.
type Adder = (a: number, b: number) => number;
function iTakeAnAdder(adder: Adder) {
return adder(1, 2);
}
iTakeAnAdder((a, b) => {
a = 'hello'; // Error: cannot assign `string` to a `number`
return a + b;
});
Структурированные
Эти простые правила также применяются к структурированному существованию (объектные литералы), например, тип foo
выводится как { a: number, b: number }
в следующих случаях:
const foo = {
a: 123,
b: 456
};
foo.a = 'hello'; // Error:cannot assign `string` to a `number`
То же самое касается массивов:
const bar = [1, 2, 3];
bar[0] = 'hello'; // Error:cannot assign `string` to a `number`
Если параметры функции могут быть выведены, то и могут быть деконструированы. В следующем примере параметры функции могут быть деконструированы в члены a/b
:
type Adder = (number: { a: number; b: number }) => number;
function iTakeAnAdder(adder: Adder) {
return adder({ a: 1, b: 2 });
}
iTakeAnAdder(({ a, b }) => {
// a, b Могут быть выведены
a = 'hello'; // Error:cannot assign `string` to a `number`
return a + b;
});
Тип защиты
В предыдущей главе Защита типов мы уже знали, как она может помочь нам изменить и сузить тип (особенно при объединении типов). Защита типов - это просто еще одна форма вывода переменных в блоке.
Предупреждения
Будьте осторожны с параметрами
Если тип не может быть выведен с помощью присваивания, тип не попадет в параметры функции. Например, в следующем примере компилятор не знает тип foo
, поэтому он не может определить тип a
или b
.
const foo = (a, b) => {
/* do something */
};
Однако, если foo
описан по типу, параметры функции также могут быть выведены (a,
b
может быть выведен как number
):
type TwoNumberFunction = (a: number, b: number) => void;
const foo: TwoNumberFunction = (a, b) => {
/* do something */
};
Будьте осторожны с возвращаемыми значениями
Хотя TypeScript может обычно выводить возвращаемое значение функции, это может быть не то, что вам нужно. Например, следующая функция foo
возвращает any
:
function foo(a: number, b: number) {
return a + addOne(b);
}
// Некоторые специальные функции, использующие библиотеки JavaScript
function addOne(a) {
return a + 1;
}
Это связано с тем, что на тип возвращаемого значения влияет функция addOne
, в которой отсутствует определение типа (значит оно равно any
, поэтому addOne
возвращает any
, а foo
также возвращает any
).
Вот некоторые другие сценарии, которые вы можете себе представить, но хорошая новость заключается в том, что есть опция компилятора noImplicitAny
для обнаружения этих ошибок.
noImplicitAny
noImplicitAny
Опция noImplicitAny
используется, чтобы сообщить компилятору о возникновении ошибки, когда он не может вывести переменную (или он может быть выведен как неявный any
тип), вы можете:
Сделать его
any
типом, явно добавив аннотацию типа:any
;Помочь TypeScript вывести типы с некоторыми более правильными аннотациями типов.
Last updated
Was this helpful?