TS基础

房东的猫 提交于 2020-02-28 13:35:18

1、函数声明、定义、使用

1581337456535-image.png

函数声明:制定函数的参数和返回值类型

函数实现:函数具体的实现,参数可少于等于函数的定义。函数实现参数TS会根据函数的声明进行推断

函数调用:函数的调用参数必须要和函数的声明一致,不然会报错

 

2、索引签名

TS支持字符串和数字索引,可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型

 

3、 强制类型转换

  • as

  • 利用泛型

interface Square {
    color: string;
  	sideLength: number
}
let square = <Square>{}; // 强制类型转换,并进行初始化
square.color = "blue";
square.sideLength = 10;

 

4、类

  • 访问修饰符(都是针对实例属性)

    • private:私有,只能在本类和实例中被访问

    • protect:受保护,在本类以及其派生类中可被访问

    • public:不受限制

  • 静态属性、实例属性

    • 实例属性需要在被实例化时进行初始化,静态属性挂在类上,类存在,静态属性就存在。

    • 实例属性、方法只能实例方法中访问,静态属性和方法可以在实例方法和静态方法中被访问

 

5、类型保护

  1. 交叉类型

obj: A & B & C,obj必须包含有A、B、C中的所有属性,均可直接访问

2. 联合类型

obj:A | B,obj是A或者是B类型,obj中一定包含A和B共有的属性,但是非公有属性不能直接访问,直接访问会报错,所以引出下面的类型保护

3. 类型保护

联合类型中非公有的属性不可直接访问,编译不通过

interface Bird {
    fly();
    layEggs();
}

interface Fish {
    swim();
    layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
// 每一个成员访问都会报错
if (pet.swim) {
    pet.swim();
}
else if (pet.fly) {
    pet.fly();
}

可通过已下几种方式进行处理

  • 类型断言

    let pet = getSmallPet();
    
    if ((<Fish>pet).swim) {
        (<Fish>pet).swim();
    }
    else {
        (<Bird>pet).fly();
    }
  • 户自定义的类型保护

    function isFish(pet: Fish | Bird): pet is Fish {
        return (<Fish>pet).swim !== undefined;
    }
    
    // 'swim' 和 'fly' 调用都没有问题了
    
    if (isFish(pet)) {
        pet.swim();
    }
    else {
        pet.fly();
    }
  • typeof类型保护

    function a(padding: string | number): string | number {
      if (typeof padding === 'number') {
      } else {
      
      }
    }
  • instanceof类型保护

与typeof类型保护类似

 

6、null、undefined

  • null、undefine的是其他类型的子集,当你声明一个变量时,它会自动地包含 null或 undefined;使用--strictNullChecks,将不允许将二者赋值给其他类型,除非对变量进行联合类型声明

let s = "foo";
s = null; // 错误, 'null'不能赋值给'string'
let sn: string | null = "bar";
sn = null; // 可以

sn = undefined; // error, 'undefined'不能赋值给'string | null'
  • null 和undefined属于不同类型

  • 使用了 --strictNullChecks,可选参数会被自动地加上 | undefined

function f(x: number, y?: number) {
    return x + (y || 0);
}
f(1, 2);
f(1);
f(1, undefined);
f(1, null); // error
  • 手动排除null/undefined

可在变量后面添加'!'

function postfix(name: string | null) {
    return name!.charAt(0) + '.  the '; // 排除null和undefined
  }

 

7、特殊类型demo

  • Exclude<T, U> -- 从T中剔除可以赋值给U的类型。

  • Extract<T, U> -- 提取T中可以赋值给U的类型。

  • NonNullable<T> -- 从T中剔除null和undefined。

  • ReturnType<T> -- 获取函数返回值类型。

  • InstanceType<T> -- 获取构造函数类型的实例类型。

  • Pick<T, K> -- 获取T中的K属性,属性值类型不变 【同态】

interface Person {
    name: string;
    age?: number;
}
 type person5 = Pick<Person, "name">;
// person5 === {name: string}

 

  • Partial<T> -- T中属性变为可选属性,属性值类型不变【同态】

  • Readonly<T> -- T中属性变为只读属性,属性值类型不变【同态】

  • Record<K, T> 拷贝K中属性,新定义属性值类型为T【不同态】, https://www.leevii.com/2018/10/record-in-typescript.html

【不同态:表示必须输入属性值类型,拷贝属性定义新类型】

 

8、命令空间

  • 命名空间区分文件但是隶属同一个命名空间时,可以通过<reference path="Validation.ts" />进行关联

  • 文件输出可以按照顺序输出到一个文件,或者是分别输出,但是均需引用

image.png

 

9、模块查找

  • 相对模块:本地模块,通过相对路径引用,如:import * as from './hhh.js'

  • 非相对模块:npm模块,通过模块名引用,如 import moment from 'moment'

a. 模块查找路径设置

	"baseUrl": "./",                          /* Base directory to resolve non-absolute module names. */
  "paths": {                                /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    "@assets/*": ["src/assets/*"],
    "react-native": ["node_modules/@mrn/react-native"],
    "@mfe/react-native-vector-icons/FontAwesome": ["node_modules/@types/react-native-vector-icons/FontAwesome"],
    "moment/min/moment.min.js": ["node_modules/moment"]
	},
  
  • 设置baseUrl来告诉编译器到哪里去查找模块。 所有非相对模块导入都会被当做相对于 baseUrl。注意相对模块的导入不会被设置的baseUrl所影响,因为它们总是相对于导入它们的文件

    baseUrl的值由以下两者之一决定:

    • 命令行中baseUrl的值(如果给定的路径是相对的,那么将相对于当前路径进行计算)

    • ‘tsconfig.json’里的baseUrl属性(如果给定的路径是相对的,那么将相对于‘tsconfig.json’路径进行计算)

  • 设置path相当于配置地址别名,react-native本来需要通过‘@mrn/react-native’形式引用,现在可以直接通过'react-native'形式引用

 

b. 利用rootDirs指定虚拟目录

{
  "compilerOptions": {
    "rootDirs": [
      "src/views",
      "generated/templates/views"
    ]
  }
}

构建过程中会将上面两个目录下的文件拷贝到一个文件目录下,这样在src/views目录下的文件中使用template/views中的文件时,可以通过'./template.js'形式访问

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!