1. 类型对比
JS:String、Number、Boolean、Null、Undefined、++Object++、Symbol (ES6);
TS:boolean 、number、string、null、 undefined、 Symbol、++void 空类型、any 类型,never等++;
2.联合类型
(1) 联合类型可以访问 string 和 number 的共有属性
type possible = string | number
function getLength (param: possible): string {
return param.toString() // 必须是共有属性
}
(2)联合类型的变量在被赋值的时候,会根据类型推论推断出一个类型
let myNumber: string | number
myNumber = 'Seven'
console.log(myNumber.length)
3.类型断言
可以用来手动指定一个值的类型, 需要注意的是,类型断言只能够避免TypeScript 编译器,无法避免运行时的错误,反而滥用类型断言可能会导致运行时错误
类型声明是比类型断言更加严格的,尽量不要使用断言。
- 联合类型可以被断言为其中一个类型
- 父类可以被断言为子类
- 任何类型都可以被断言为 any
- any 可以被断言为任何类型
function toBoolean(a:any):boolean{
return a as boolean
}
toBoolean(1) // 返回值为1
// 类型断言不是类型转换,它不会真的影响到变量的类型。
function toBoolean(a:any):boolean{
return Boolean(a)
}
toBoolean(1) // 返回值为true
4.泛型
是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性
- 函数参数可能存在多种类型;
- 函数可能会被多次调用;
// 1.使用any
function createArray1(length: any, value: any): Array<any> {
let result: any = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
let result = createArray1(3, 'x');
console.log(result);
// 2.每种类型都得定义一种函数(麻烦)
function createArray2(length: number, value: string): Array<string> {
let result: Array<string> = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
function createArray3(length: number, value: number): Array<number> {
let result: Array<number> = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
// 3.使用函数重载(麻烦)
function createArray4(length: number, value: number): Array<number>
function createArray4(length: number, value: string): Array<string>
function createArray4(length: number, value: any): Array<any> {
let result: Array<number> = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray4(6, '666');
//4.有关联的地方都改成 <T> *******
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
// 使用的时候再指定类型
let result = createArray<string>(3, 'x');
// 也可以不指定类型,TS 会自动类型推导
let result2 = createArray(3, 'x');
console.log(result);
// 传入两个类型
function identity<T, U>(value: T, message: U): T {
console.log(message)
return value
}
const res = identity<number, string>(123, '信息')
console.log(res) // 信息 123
5.报错问题
1.null 和 undefined是其它类型(包括void)的子类型,可以赋值给其它类型
//tsconfig.json
strictNullChecks:true,//默认无法赋值
strictNullChecks:false,//改为false可以赋值
2.never 和 void 的区别
- void 表示没有任何类型(可以被赋值为 null 和 undefined)。
- never 表示一个不包含值的类型,即表示永远不存在的值。
- 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。
3.元祖越界问题
let arr: [string, number] = ['aaa', 5];
arr.push(6);
//arr.push(true);
//arr[2]='ddd';
console.log(arr); // ['aaa',5,6];
console.log(arr[2]); // error
4.全局环境中给某些特定变量声明类型报错
let name:string // 报错,与全局name冲突
// 解决方案,模块化
6.可选链运算符与非空断言
a?.b;
// 相当于 a == null ? undefined : a.b;
// 如果 a 是 null/undefined,那么返回 undefined,否则返回 a.b 的值.
a?.[x];
// 相当于 a == null ? undefined : a[x];
// 如果 a 是 null/undefined,那么返回 undefined,否则返回 a[x] 的值
a?.b();
// 相当于a == null ? undefined : a.b();
// 如果 a 是 null/undefined,那么返回 undefined
// 如果 a.b 不是函数的话,会抛类型错误异常,否则计算 a.b() 的结果
//非空断言符的使用 !.
let root: (HTMLElement | null) = document.getElementById('root');
root!.style.color = 'red';
// 非空断言操作符--> 这样写只是为了骗过编译器,防止编译的时候报错,打包后的代码可能还是会报错
7.类型大小写???
/* 错误 */
function reverse(s: String): String;
/* OK */
function reverse(s: string): string;
8.*.d.ts!!!
- 引入外部模块
- 声明全局变量
使用 import 引入非 JS 模块会报错,而使用 require 则没有问题
解决:给非JS模块添加申明