【知识网】TypeScript系统学习之基本类型详解

298 阅读4分钟

基本类型

  1. TS的基本类型和JS的基本类型完全相同。

object/boolean/number/string

null/undefined

symbol:es6新加,实例唯一且不可改变

let you: boolean/string/number = false/'xxx'/100;
let list: number[]/Array<number> = [1,2,3];
  • 与java类型比较:

  • TS可以根据指定的变量进行类型推断,中途更改变量类型会触发TS编译报错。
  • 类型断言——提前指定类型,第一种用“尖括号”;第二种用关键字as。
let oneString:any = "this is jack";
let oneLength:number = (<string>oneString).length;
let oneLength:number = (oneString as string).length; // jsx中类型断言只能使用as

除基本类型外,TS还有泛型,枚举,symbol,iterator,generator等。

泛型

  1. 泛型函数和泛型变量

当需要表达函数的参数类型和返回值类型必须保持一致,使用any会导致类型混乱,这时我们可以考虑使用泛型。

function hello<T>(arg:T):T{
	retrun arg;
}
// 或
function hello<T>(arg:T[]):T[]{
	retrun arg;
}
// 或
function hello<T>(arg:Array<T>):Array<T>{
	retrun arg;
}

先给hello函数通过<>添加泛型T,再申明参数类型T和返回值类型T。

在使用泛型函数时,可以给泛型赋值,也可以省略。

let out = hello<string>('hello world');
let out = hello('hello world'); // 让TS根据传入道德参数类型推断出泛型T的值

凡事皆有例外,再某些特殊复杂的情况下,类型推断会失灵的,这时就需要我们明确地给泛型T赋值。

枚举

  1. 数字枚举和字符串枚举

TS支持数字类型枚举和字符串类型枚举。

enum OrderStatus{
  Start=1,
  Unpaid, // 默认递增,也可以赋值
  Shipping,
  Shipped,
  Complete
}
  • 如果枚举中都不赋值,默认从0开始,依次递增。
  • 枚举值都必须是确定的。
  • 字符串枚举都必须赋值。
  1. 数字枚举的反向映射

由于TS枚举代码会编译成JS代码实现,所以数字枚举可以从key到value正向映射,也可以从value到key反向映射。

// TS枚举
enum Enum {
	A = 1;
}
// JS枚举实现
(function (Enum){
	Enum[Enum["A"] = 1] = "A";
})(Enum || (Enum = {}));
// 正向映射
const a = Enum.A; //1
//反向映射
const nameOfA = Enum[a]; //"A"
  • 字符串枚举没有反响映射;

symbol

es6新加,实例唯一且不可改变。

TS中使用symbol类型和es6一样通过Symbol构造函数创建;

const symbol1 = Symbol(); 
const symbol2 = Symbol('hello');
const symbol3 = Symbol('hello');
console.log(symbol2 === symbol3); // 实例唯一,false。
  • symbol可以像字符串一样用作对象属性的健;
const symbol = Symbol();
const obj = {
	[symbol]: "hello";
};
console.log(obj[symbol]); // "hello"

iterator

实现了Symbol.iterator方法的对象,Symbol.iterator方法返回供迭代的值。

eg:array、map、set、string、int32Array、uint32Array等内置类型。

常用的 for...of/in/each等会调用可迭代对象的Symbol.iterator方法。


const array =[1,false,'hello'];
for (let val of array){
	console.log(val); // 1 , false, 'hello'
}
for (let i in array){
	console.log(i); // 0,1,2
}

总结:

1. for...of 迭代的是对象的键,而for...in迭代的是对象的值。

2. for...of 只可操作可迭代对象,而for...in可操作任意对象。

\

Set是不重复数组,没有下标,for in和下标访问无效或报错,有size没length。

const nameSet= new Set('Js','Ja','Ph','Py');
nameSet[9] = 'Ru';

generator...yield

generator函数的语法是function * , MDN文档中称为生成器。调用generator方法,会返回一个generator对象。generator对象遵循迭代器接口,可以使用常见的next,return,throw函数。

generator函数的实质是允许一个函数暂停执行,当调用next() 之后,函数执行到yield语句时会暂停并返回yield的值对象,再次调用会接着上次返回第二个yield返回值对象。

所以我的理解是generator是间断执行函数,也可以叫片段执行函数。

其中return函数一般通过yield关键词来实现;

如果在generator函数中直接使用return,return之前的函数仍然可以分段执行,return之后的代码无效;

// 创建generator函数
function * generatorFn(){
	console.log('执行代码片段一');
  yield 1;
  console.log('执行代码片段二');
  yield 2;
  console.log('执行代码片段三');
  const num = yield 3;
  console.log('执行结束'+num);
}

// 生成 generator 对象
const gen = generatorFn();

// 调用next(), 让代码分片段执行
console.log(gen.next());
// 执行代码片段一
// {value: 1, done: false};
console.log(gen.next());
// 执行代码片段二
// {value: 2, done: false};
console.log(gen.next());
// 执行代码片段三
// {value: 3, done: false};
console.log(gen.next(4));
// 执行结束4
// {value: undefined, done: true};

yield 有两种用法:

  • 返回当前next函数返回值;//实现return功能
  • 接收下一个next函数的传参;

下面看gen.throw函数

function * generator(){
	try {
    
  	yield 1;
  }catch(error){
		console.log(error.message);
  }
}
const gen = generator();
console.log(gen.next()); 
// {value: 1, done:false}
console.log(gen.throw(new Error('执行出错'))); 
// 执行出错
// {value: undefined, done: true}

在generator函数中使用return;

// 创建generator函数
  function* generatorFn() {
    console.log('执行代码片段一');
    yield 1;
    console.log('执行代码片段二');
    return '333';
    yield 2;
    console.log('执行代码片段三');
    const num = yield 5;
    console.log('执行结束' + num);
  }

  // 生成 generator 对象
  const gen = generatorFn();

  // 调用next(), 让代码分片段执行
  console.log(gen.next());
  // 执行代码片段一
  // {value: 1, done: false};
  console.log(gen.next());
  // 执行代码片段二
  // {value: '333', done: false};
  console.log(gen.next());
  // {value: undefined, done: false};
  console.log(gen.next(3));
  // {value: undefined, done: true};

直接使用return函数,return之前的部分依旧可以分段执行,return之后的代码无效;