Используйте TypeScript умело (3)

внешний интерфейс JavaScript TypeScript
Используйте TypeScript умело (3)

Массивы и кортежи

Создать массив просто:

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 }).

Более