TypeScript 学习笔记 — 类型推断和类型保护

Posted Echoyya、

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 学习笔记 — 类型推断和类型保护相关的知识,希望对你有一定的参考价值。

类型推断

TypeScript 编译器会根据一些简单的规则来推断开发者定义的变量的类型,​ 当没有标明变量的类型时,编译器会将变量的初始值作为该变量的类型

1.赋值推断

赋值时推断,类型从右像左流动,会根据赋值推断出变量类型,这种是比较常见的,声明时不需要给类型

let str = "zhufeng";
let age = 11;
let boolean = true;

2.返回值推断

自动推断函数返回值类型

function sum(a: string, b: string) 
  return a + b;

sum("a", "b");

3.函数推断(反向推断)

函数从左到右进行推断(上下文类型):先声明一个函数类型,后把这个类型赋予给一个变量,在赋值一个函数,再看被赋值的函数是否满足,事先声明的函数类型,
上下文类型推断时,会根据参数的位置进行相应的推断,函数的参数多的时候,就会推断失败报错

type Sum = (a: string, b: string) => string; // 函数类型
const sum: Sum = (a, b) => a + b; // 还可以根据函数类型,推导出函数参数和返回值的类型

type ICallback = (x: string, y: string) => void; // 不关心返回值

function fn(cb: ICallback) 
  let r = cb("1", "2"); // 调用函数后不会根据返回值来推导,默认采用就是上下文中声明的类型


fn((a, b) => );

4.属性推断

可以通过属性值,推断出属性的类型

let person = 
  name: "yyya",
  age: 18,
;
let  name, age  = person; // string  number

5.类型反推

可以使用 typeof 关键字反推变量类型

let person = 
  name: "yyya",
  age: 18,
;
type Person = typeof person; // type Person = name: string; age: number;

6.索引访问操作符

interface IPerson 
  name: string;
  age: number;
  job: 
    address: string;
  ;

type job = IPerson["job"]; // type job =  address: string; 

7.类型映射

interface IPerson 
  name: string;
  age: number;

type MapPerson =  [key in keyof IPerson]: IPerson[key] ; // type MapPerson = name: string; age: number;

类型保护

TypeScript 能够在特定的区块中保证变量属于某种确定的类型。可以在此区块中放心的引用此类型的属性,或者调用此类型的方法
通过判断识别所执行的代码块,自动识别变量属性和方法

1.typeof 类型保护

判断基本类型:ts 默认在使用联合类型,针对某一种类型进行处理,对不同的类型进行范围缩小

function double(a: string | number) 
  if (typeof a === "string") 
    return a + a;
   else 
    return a * 2;
  

2.instanceof 类型保护

判断一个实例是否属于某个类

class Cat 
class Dog 

const getInstance = (clazz:  new (...args: any[]): Cat | Dog ) => 
  return new clazz();
;
let r = getInstance(Cat);
if (r instanceof Cat) 
  r;
 else 
  r;

3.in 类型保护

判断一个属性是否属于某个对象

interface Bird 
  fly: string;

interface Fish 
  swim: string;


function getType(type: Bird | Fish) 
  if ("swim" in type) 
    type;
   else 
    type;
  

4.可辨识联合类型

通过接口中的 kind 作为可辨识类型

interface Bird 
  fly: string;
  kind: "鸟";

interface Fish 
  swim: string;
  kind: "鱼";

function getType(type: Bird | Fish) 
  if (type.kind == "鸟") 
    type;
   else 
    type;
  


// 判断一个变量是数组,通过其类型来辨识
function ensureArray<T>(input: T | T[]): T[] 
  if (Array.isArray(input)) 
    return input;
   else 
    return [input];
  

5.null 保护

变量判空给默认值的方式实现

function addPrefix(num?: number) 
  num = num || 0; // null 保护
  return function (prefix: string) 
    return prefix + num!.toFixed();
  ;

let r = addPrefix()("$");

6.自定义类型保护

直接调用isBird方法不确认 返回 true 是 Bird,还是返回 false 是 Bird,因此工具方法中判断类型的方法 全部需要使用 is 语法

function isBird(val: Bird | Fish | (string &  kind: "string" )): val is Bird 
  return val.kind == "鸟"; // 必须是boolean

function getType(val: Bird | Fish) 
  if (isBird(val)) 
    // 此时不确认 返回true是Bird,还是返回false是Bird
    val;
   else 
    val;
  

以上是关于TypeScript 学习笔记 — 类型推断和类型保护的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 类型推断、扩展语法和多类型返回

Typescript 和 React:使用 React.Component 和条件类型化道具时类型推断失败

TypeScript——类型检查机制

TypeScript:推断嵌套联合类型的类型

TypeScript 类型推断 - 函数的通用对象

条件类型中的 TypeScript 类型推断