TS类型保护和字面量类型

327 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

类型保护

类型保护可以很好的增强js的健壮性,避免一些风险

const getValue1 = () => {
  const num = Math.random();

  return num > 0.5 ? num : 'a';
};

const value1 = getValue1();

如果直接使用

if (value1.length) {
} 

value1.length 直接使用会报错,getValue1 返回值的类型是 number | string

利用泛型解决

if ((<string>value1).length) {
  console.log((value1 as string).length);
} else {
  console.log((value1 as number).toFixed(2));
}

利用 typeof 解决:

ts 中使用 typeof 有些要求

只能使用 === 或 !== 两种形式进行比较, 可以使用 typeof === 'string', 不能 (typeof val).includes('string)

Typeof 把 number, string, boolean, symbol 四种类型视为 保护类型, 例如 typeof obj === 'object', ts 只会将其视为js语句,不具有保护类型的作用

if (typeof value1 === 'string') {
  console.log(value1.length);
} else {
  console.log(value1.toFixed(2));
}

利用 instanceof 解决:

if (obj1 instanceof String) {
  console.log(value1.length);
} else {
  console.log(value1);
}

自定义类型保护:

function isStr(val: number | string): val is string {
  return typeof val === 'string';
}

if (isStr(value1)) {
  console.log(value1.length);
} else {
  console.log(value1.toFixed(3));
}

显示复制断言

严格模式下 null 和 undefined 区别

若是在tsconfig.json 中将 strictNullChecks 设置为 true之后,就不能在将 null 和 undefined 赋值给除了他俩自身和 void 以外的其他任意类型值了,但是在开发过程中,的确会存在将他俩赋值给一个初始化的变量,然后根据业务逻辑再进行赋值,这时候就需要使用联合类型了

let showVar1 = 'showVar1';
// showVar1 = null; // error
let showVar2: string | null = 'showVar2';
showVar2 = null;
// showVar2 = undefined; // error, ts是将 null 和 undefined 区分的,number|null 和 number|undefined 是不一样的

可选参数&可选属性:

如果配置开启 strictNullChecks 之后,可选参数和可选属性会自动加上 | undefined

//  n2 的类型是联合类型 number|undefined
const selectVar = (n1: number, n2?: number) => {};
selectVar(1, undefined);
// selectVar(1, null);  // error

interface SelectVarInterface {
  name: string;
  age?: number;
}

let selectVarInterface: SelectVarInterface = {
  name: 'nordon',
  age: undefined
  // age: null // error
};

字面量类型

字符串字面量类型: 字符串字面量类型其实就是字符串常量,与字符串类型不同的是它是具体的值。

type ConstStr = 'nordon';
// let cs1: ConstStr = 'wy'; // error

type Direction = 'left' | 'right' | 'top' | 'bottom';

const getDirection = (direction: Direction): string => {
  return direction.slice(0);
};
// getDirection('test'); // error test 不在 定义好的几个里面
getDirection('right');

数字字面量类型: 另一个字面量类型就是数字字面量类型,它和字符串字面量类型差不多,都是指定类型为具体的值。

type Age = 18;

interface InfoNumber {
  name: string;
  age: Age;
}

let info1: InfoNumber = {
  name: 'nordon',
  age: 18
  // age: 22 // error age 只能是 18
};