5万字 TypeScript入门系列(第四期)(建议收藏)

Posted 极客江南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5万字 TypeScript入门系列(第四期)(建议收藏)相关的知识,希望对你有一定的参考价值。

极客江南: 一个对开发技术特别执着的程序员,对移动开发有着独到的见解和深入的研究,有着多年的iosandroidhtml5开发经验,对NativeApp、HybridApp、WebApp开发有着独到的见解和深入的研究, 除此之外还精通 javascript、AngularJS、 NodeJS 、Ajax、jQuery、Cordova、React Native等多种Web前端技术及Java、php等服务端技术。

初学者玩转 TypeScript系列,总计 10 期,本文为第 4 期,点赞、收藏、评论、关注、三连支持!

一期知识点击这里

二期知识点击这里

三期知识点击这里

对于初学者来说,学习编程最害怕的就是,

那么,Typescript 是不是很难?

首先,我可以肯定地告诉你,你的焦虑是多余的。新手对学习新技术有很强的排斥心理,主要是因为基础不够扎实,然后自信心不够强。

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

  • TS中支持两种枚举, 一种是数字枚举, 一种是字符串枚举
  • 数字枚举
  • 默认情况下就是数字枚举

enum Gender{
    Male,
    Female
}
console.log(Gender.Male);
console.log(Gender.Female);
  • 数字枚举注意点
  • 数字枚举的取值默认从0开始递增
  • 数字枚举的取值可以是字面量, 也可以是常量, 也可以是计算的结果

const num = 666;
function getNum() {
    return 888;
}
enum Gender{
    // Male = 6,
    // Male = num, // 注意点: 如果使用常量给前面的枚举值赋值了, 那么后面的枚举值也需要手动的赋值
    // Female = 8
    Male = getNum(), // 注意点: 如果使用计算结果给前面的枚举值赋值了, 那么后面的枚举值也需要手动的赋值
    Female = 123
}
  • 枚举反向映射
// 可以根据枚举值获取到原始值
// 也可以根据原始值获取到枚举值
enum Gender{
    Male,
    Female
}
console.log(Gender.Male); // 0
console.log(Gender[0]); // Male

  • 字符串枚举
enum Gender{
    Male = 'www.it666.net',
    Female = 'www.itzb.net' // 注意点: 如果使用字符串给前面的枚举值赋值了, 那么后面的枚举值也必须手动赋值
}
console.log(Gender.Male);
console.log(Gender.Female);
  • 字符串枚举注意点
  • 注意点: 如果使用字符串给前面的枚举值赋值了, 那么后面的枚举值也必须手动赋值
  • 注意点: 和数字枚举不一样, 字符串枚举不能使用常量或者计算结果给枚举值赋值
  • 注意点: 虽然字符串枚举不能够使用常量或者计算结果给枚举值赋值, 但是它可以使用内部的其它枚举值来赋值
const str = 'lnj';
function getStr() {
    return 'abc';
}
enum Gender{
    Male = 'www.it666.net',
    // Male = str,
    // Male = getStr(),
    Female = 'www.itzb.net',
    Yao = Female
}
console.log(Gender.Female);
console.log(Gender.Yao);
  • 异构枚举
  • 枚举中既包含数字又包含字符串, 我们就称之为异构枚举
enum Gender{
    Male = 6,
    Female = 'nv'
}

console.log(Gender.Male);
console.log(Gender.Female);
console.log(Gender[6]);
// 注意点: 如果是字符串枚举, 那么无法通过原始值获取到枚举值
// console.log(Gender['nv']);
console.log(Gender);

2. 枚举成员类型和联合类型

  • 枚举成员类型

  • 我们就可以把枚举成员当做类型来使用

enum Gender{
    Male = 'www.it666.com',
    Female = 'www.itzb.com'
}
interface TestInterface {
    age: Gender.Male
}
class Person implements TestInterface{
    age: Gender.Male
    // age: Gender.Female // 由于类型不匹配, 所以会报错
    // age: 0 // 注意点: 由于数字枚举的本质就是数值, 所以这里写一个数值也不会报错

    // age: Gender.Male
    // age: Gender.Female
    // age: 'www.it666' // 注意点: 如果是字符串枚举, 那么只能是枚举成员的值, 不能是其它的值
    // age: string
}
  • 联合枚举类型
  • 什么是联合类型?
  • 联合类型就是将多种数据类型通过|连接起来
  • 我们可以把枚举类型当做一个联合类型来使用
let value:(number | string); // (number | string)联合类型
value = 1;
value = 6;
value = "123";

enum Gender{
    Male ,
    Female
}
interface TestInterface {
    age: Gender // age: (Gender.Male | Gender.Female)
}
class Person implements TestInterface{
    // age: Gender.Male
    age: Gender.Female
}

3.运行时和常量枚举

// 运行时枚举
// 枚举在编译之后是一个真实存储的对象, 所以可以在运行时使用
// 而像接口这种只是用来做约束做静态检查的代码, 编译之后是不存在的

interface TestInterface {
    name:string;
    age:number;
}
enum Gender{
    Male,
    Female
}

  • 常量枚举
// 普通枚举和常量枚举的区别
// 普通枚举会生成真实存在的对象
// 常量枚举不会生成真实存在的对象, 而是利用枚举成员的值直接替换使用到的地方
enum Gender1{
    Male,
    Female
}
console.log(Gender1.Male === 0);

const enum Gender2{
    Male,
    Female
}
console.log(Gender2.Male === 0);

4. 类型推论

  • 什么是自动类型推断?
  • 不用明确告诉编译器具体是什么类型, 编译器就知道是什么类型
// 1.根据初始化值自动推断
// 如果是先定义在初始化, 那么是无法自动推断的
// let value;
// value = 123;
// value = false;
// value = 'abc';

// 如果是定义的同时初始化, 那么TS就会自动进行类型推荐
// let value = 123; // let value:number = 123;
// value = 456;
// value = false;
// value = 'abc';

let arr = [1, 'a']; // let arr:(number | string) = [1, 'a'];
arr = ['a', 'b', 'c', 1, 3, 5, false]

// 2.根据上下文类型自动推断
window.onmousedown = (event)=>{
    console.log(event.target);
}

5. 类型兼容性

// 基本兼容性
/*
interface TestInterface {
    name:string;
}

let p1 = {name:'lnj'};
let p2 = {age:18};
let p3 = {name:'lnj', age:18};

let t:TestInterface;
t = p1;
t = p2;
t = p3; // 可多不可少
 */
/*
interface TestInterface {
    name:string;
    children:{
        age:number
    };
}

let p1 = {name:'lnj', children:{age:18}};
let p2 = {name:'lnj',children:{age:'abc'}};

let t:TestInterface;
t = p1;
t = p2; // 会递归检查
 */

6. 函数兼容性

// 参数个数
/*
let fn1 = (x:number, y:number)=>{};
let fn2 = (x:number)=>{};
fn1 = fn2;
fn2 = fn1; // 可少不可多
 */

// 参数类型
/*
let fn1 = (x:number)=>{};
let fn2 = (x:number)=>{};
let fn3 = (x:string)=>{};
fn1 = fn2;
fn2 = fn1;
fn1 = fn3; // 必须一模一样
fn3 = fn1;
 */

// 返回值类型
/*
let fn1 = ():number=> 123;
let fn2 = ():number=> 456;
let fn3 = ():string=> 'abc';
fn1 = fn2;
fn2 = fn1;
fn1 = fn3; // 必须一模一样
fn3 = fn1;
 */

// 函数双向协变
/*
// 参数的双向协变
// let fn1 = (x:(number | string)) =>{};
// let fn2 = (x:number) =>{};
// fn1 = fn2;
// fn2 = fn1;

// 返回值双向协变
let fn1 = (x:boolean):(number | string) => x ? 123 : 'abc';
let fn2 = (x:boolean):number => 456;
// fn1 = fn2; // 但是可以将返回值是具体类型的赋值给联合类型的
fn2 = fn1; // 不能将返回值是联合类型的赋值给具体类型的
 */

// 函数重载
function add(x:number, y:number):number;
function add(x:string, y:string):string;
function add(x, y) {
    return x + y;
}

function sub(x:number, y:number):number;
function sub(x, y) {
    return x - y;
}

// let fn = add;
// fn = sub; // 不能将重载少的赋值给重载多的

let fn = sub;
fn = add; // 可以将重载多的赋值给重载少

7. 枚举兼容性

// 数字枚举与数值兼容
/*
enum Gender{
    Male,
    Female
}
let value:Gender;
value = Gender.Male;
value = 1
 */

// 数字枚举与数字枚举不兼容
/*
enum Gender{
    Male, // 0
    Female // 1
}
enum Animal{
    Dog, // 0
    Cat // 1
}
let value:Gender;
value = Gender.Male;
value = Animal.Dog; // 报错
*/

// 字符串枚举与字符串不兼容
/*
enum Gender{
    Male = 'abc',
    Female  = 'def'
}
let value:Gender;
value = Gender.Male;
value = 'abc';
 */

8. 类兼容性

// 只比较实例成员, 不比较类的构造函数和静态成员
/*
class Person {
    public name:string;
    // public age:number;
    public static age:number;
    constructor(name:string, age:number){}
}
class Animal {
    public name:string;
    constructor(name:string){}
}
let p: Person;
let a: Animal;
p = a;
a = p; // 可多不少
 */

// 类的私有属性和受保护属性会响应兼容性
/*
class Person {
    protected name:string;
}
class Animal {
    protected name:string;
}
let p: Person;
let a: Animal;
p = a;
a = p; // 可多不少
 */

9. 泛型兼容性

// 泛型只影响使用的部分, 不会影响声明的部分
interface TestInterface<T> {
    // age:T;
}
let t1: TestInterface<number>; // age:number
let t2: TestInterface<string>; // age:string
t1 = t2;
t2 = t1;

码字不易,在线求个三连支持。

大家记得收藏前,先点个赞哦!好的文章值得被更多人看到。

推荐阅读:

13万字C语言保姆级教程2021版

10万字Go语言保姆级教程

2 万字 Jquery 入门教程

3 万字 html +css 入门教程

169集保姆级C语言视频

最后,再多一句,粉丝顺口溜,关注江哥不迷路,带你编程上高速。

版权所有,请勿转载,转载请联系本人授权

以上是关于5万字 TypeScript入门系列(第四期)(建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章

5万字 TypeScript入门系列(第三期)(建议收藏)

5万字 TypeScript入门系列(第三期)(建议收藏)

湖上建仓全解析:如何打造湖仓一体数据平台 | DEEPNOVA技术荟系列公开课第四期

Lenovo系列问题第四期

红帽Linux入门指南第四期:系统的基本操作命令

逻辑运算 — 白话Lua系列零基础教程 第四期