Массивы и кортежи
Создать массив просто:
const arr = [1];
В этот момент TypeScript сделает выводarrТипnumber[]:
arr.push('1'); // Error
Когда элементы массива имеют другие типы, вы можете использовать аннотации типов:
const arr: Array<string | number> = [1];
arr.push('1'); // OK
arr.push(true); // Error
Или вы можете передать необязательные кортежи:
const arr: [number, string?] = [1]; // arr 的成员类型可以是: number, string, undefined
arr.push('1'); // OK
arr.push(true); // Error
Форма кортежей, проверка типа может обеспечить указанное место:
arr[0] = '1'; // Error
arr[1] = 1; // Error
использовать
Обычно мы используемPromise.allСделайте несколько запросов параллельно:
interface A {
name: string;
}
interface B {
age: number;
}
const [{ data: a }, { data: b }] = await Promise.all([
axios.get<A>('http://some.1'),
axios.get<B>('http://some.2')
])
На этом этапе TypeScript может запуститьaТипA, bТипB.
Теперь, с небольшим изменением: второй запрос сделан только при выполнении определенных условий:
// 使用类型注解
const requestList: [Promise<AxiosResponse<A>>, Promise<AxiosResponse<B>>?]
= [axios.get<A>('http://some.1')];
if (flag) {
requestList[1] = (axios.get<B>('http://some.2'));
};
const [ { data: a }, response ] = await Promise.all(requestList);
Мы ожидали, что это сработает, как ожидалось, но это не так,Promise.all(requestList), будет ошибка совместимости типов, в этомIssues, такая же проблема описана.
Теперь вы можете заставить программу работать, утверждая:
const requestList: any[] = [axios.get<A>('http://some.1')]; // 设置为 any[] 类型
if (flag) {
requestList[1] = (axios.get<B>('http://some.2'));
}
const [
{ data: a },
response
] = await Promise.all(requestList) as [AxiosResponse<A>, AxiosResponse<B>?] // 类型安全
литеральный тип
Основанный на JavaScript, TypeScript расширяет ряд литеральных типов для обеспечения точности типов.
Например, чтобы создать строковый литерал:
const a = 'hello'; // a 的类型是 'hello'
a = 'world'; // Error
Или вы также можете:
let a: 'hello' = 'hello'; // a 的类型是 'hello'
a = 'world'; // Error
Другие типы данных аналогичны.
Вы также можете определить литералы типов пересечения и объединения:
interface A {
name: string;
}
interface B {
name: string;
age: number;
}
type C = A | B;
type D = A & B;
литеральный тип объекта
Для литеральных типов объектов в TypeScript есть функция под названием «Freshness", которая также известна как более строгая проверка литерала объекта, как в следующем примере:
let someThing: { name: string };
someThing = { name: 'hello' }; // ok
someThing = { name: 'hello', age: 123 }; // Error, 对象字面量只能指定已知属性, { name: string } 类型中不存在 age 属性
let otherThing = { name: 'hello', age: 123 };
someThing = otherThing; // ok
TypeScript считает каждый созданный объектный литерал «свежим»; когда «свежий» объектный литерал присваивается переменной, возникает ошибка, если тип объекта несовместим с типом переменной (как в приведенном выше примере).someThine = { name: 'hello', age: 123 };ошибка); когда тип литерала объекта становится шире, «свежее» состояние литерала объекта исчезает (как в приведенном выше примереsomeThing = otherThing;, после назначения,someThingтипа шире).
Более практичный вариант использования выглядит следующим образом:
function logName(something: { name: string }) {
console.log(something.name);
}
const obj = {
name: 'matt',
job: 'being awesome'
}
logName(obj); // ok
logName({ name: 'matt' }); // ok
logName({ nama: 'matt' }); // Error: nama 属性在 { name: string } 属性中不存在。
logName({ name: 'matt', job: 'being awesome' }); // Error: 对象字面量只能指定已知属性,`job` 属性在这里并不存在。
Основной принцип аналогичен приведенному выше: если вы хотите использовать более строгую проверку типов, вы можете передать литерал объекта с новым состоянием (например,logName({ name: 'matt', job: 'being awesome' });). Если вы хотите передать функции еще несколько свойств, вы можете присвоить литерал объекта новой переменной, а затем передать ее функции (например,logName(obj)). Или вы можете добавить дополнительные типы к параметрам функцииfunction logName(someThing: { name: string; [key: string]: string }).