TypeScript是一种由微软开发的自由和开源的编程语言。 它是 JavaScript
的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
js | ts |
---|---|
动态编程语言 | 静态编程语言 |
边解释边执行,错误只有在运行的时候才能发现 | 先编译再执行,在写的时候就会发现错误了(ts不能直接执行,需要先编译成 js ) |
npm i -g typescript
或
yarn global add typescript
let name: string = "ll";
let age: number = 18;
let isShow: boolean = true;
let hoh: undefined = undefined;
let nwn: null = null;
let obj: object = {name: 'll', age: 18};
let big: bigint = 100n;
let sym: symbol = Symbol("ll");
//number
let age: number = 18
//string
let name: string = 'll'
let nickname: string = `A ${name}` // 支持模板字符串
//boolean
let bol: boolean = true;
//undefined
let box:undefined = undefined
//null
let box:null = null
let age: number = null
let name: string = undefined
let x: number;
x = 1; // 运行正确
x = undefined; // 运行错误
x = null; // 运行错误
//如果你非要改的话,你可以使用联合类型string | null | undefined。
let x: number | null | undefined;
x = 1; // 运行正确
x = undefined; // 运行正确
x = null; // 运行正确
//tsconfig.json
{
"compilerOptions": { //编译选项,可以被忽略,这时编译器会使用默认值
"strictNullChecks": false,
//在严格的null检查模式下,null和undefined值不包含在任何类型里,只允许赋值给void和本身对应的类型。
}
}
TS 定义函数类型需要定义输入参数类型和输出类型。
输出类型也可以忽略,因为 TS 能够根据返回语句自动推断出返回值类型。
函数没有明确返回值,默认返回 Void 类型
const fn1 = (param:string): void => {
console.log("给我传的值必须是字符哟");
console.log("我是没有返回值的箭头函数");
};
function fn2(param:string): void {
console.log("给我传的值必须是字符哟");
console.log("我是没有返回值的函数");
}
let fn3= (x: number, y: number): number => {
console.log("给我传的值必须是数字哟");
console.log("我的返回值的也是数字哟");
return x + y
}
//参数后加个问号,代表是可选参数,
//可选参数必须要放在函数入参的最后面,不然会导致编译错误。
function fn4(x:number, y:number, z?:number):number {
console.log("给我传的值必须是数字x和y哟,你可以选择传数字z也可以不传哟");
return x + y
}
let fn5= (x: number, y: number=100): number => {
return x + y
}
fn5(100)
let fn6= (x: number=100, y: number): number => {
return x + y
}
fn6(100) //报错 编译器会判定你只传了 x,没传 y。
fn6(undefined,100)
function fn7(...args:number[]):number[]{
return args
}
console.log(f8(1,2,3,4,5))//[1,2,3,4,5]
const sym1:symbol = Symbol(); //唯一值
let big: bigint = 100n //目前兼容性不是很好
可以赋予任意类型的值,可以在任意值上访问任何属性,调用任何方法,相当于Js
//不建议使用,因为这将丧失TS本来的意义
let anyNever: any = 4
anyNever= "ll"
anyNever= false
anyNever.name
anyNever.getName()
type anyNever1 = unknown | any; // any
type anyNever2 = number| any; // any
type anyNever3 = string| any; // any
未知类型的值,需要进行类型检查或类型断言才能使用, 不可以在任意值上访问属性,调用方法,且unknown类型的值不能直接赋值给其他变量
//unknown
let unknownNever:unknown="冷月心"
unknownNever.getName();//报错
unknownNever.name//报错
function divide(param: unknown) {
return param / 2;
}
//1.类型断言解决
function divide(param: unknown) {
return param as number / 2;
}
// 2、类型守卫 —— 不飘红,且确保正常执行
function divide(param: unknown) {
if (typeof param === 'number') {
// 推断出类型: number
return param / 2;
}
}
// 3、类型断言函数,抛出错误 —— 不飘红,且确保正常执行
function divide(param: unknown) {
assertIsNumber(param);
return param / 2;
}
/** 类型断言函数,抛出错误 */
function assertIsNumber(arg: unknown): asserts arg is Number {
if (!(arg instanceof Number)) {
thrownewTypeError('Not a Number: ' + arg);
}
}
let strVal: string
strVal = 'str'
strval = unknownNever// TS2322: Type 'unknown' is not assignable to type 'string'.
type unknownNever1 = unknown | null; // unknown
type unknownNever2 = unknown | undefined; // unknown
type unknownNever3 = unknown | string; // unknown
type unknownNever4 = unknown | any; // any
any | unknown |
---|---|
可以赋予任意类型的值 | 未知类型的值,需要进行类型检查或类型断言才能使用 |
可以在任意值上访问任何属性,调用任何方法 | 不可以在任意值上访问属性,调用方法,且unknown类型的值不能直接赋值给其他变量 |
没有任何类型。
const fn1 = (param:string): void => {
console.log("我是没有返回值的函数");
};
const u:void=undefined;//用法很无语,基本不会这么用
const n:void=null;//这样会报错,只有tsconfig.json中strictNullChecks属性设置为false时,null才能赋值给void
const age:void=18;//这样也会报错
永不存在的值的类型
// 异常
function fn(msg: string): never {
throw new Error(msg)
// 死循环 千万别这么写,会内存溢出
function fn(): never {
while (true) {}
let err: never;
let num: number = 4;
num = err; // OK
let arr1 : number[] = [1,2,3,4]
let arr2: Array<number> = [1, 2, 3];
let arr3: Array<number> = new Array(4); // 表示定义一个数组的长度,一般固定一个数组的长度时这个方法比较方便
let arr4 = new Array<number>(4) //这种写法和 arr3 效果是一样的
// interface 定义
interface NumberArray {
[index: number]: number;
}
let arr5: NumberArray = [1, 2, 3];
let arr2 : Array<number> = [5,6,7,8]
//数组定义后,数组内的数据类型必须和定义数组的时候的类型是一致的,否则会有错误提示,某些情况下不会编译通过。
let arr2 : Array<number> = [true,'HAHA'] //报错
元组类型就是在定义数组的时候,类型和数据的个数一开始就已经限定好了。
let arr1 : [string,number,boolean] = [ '跳跳' , 520, true ]
//元组类型在使用的时候,数据的类型的位置和数据的个数,需要和在定义元组的时候的数据类型和位置相一致,不一致则会报错提示
let arr2 : [string,number,boolean] = ['跳跳',true,520] // 报错
//可以对元组内的值进行更改
let arr3 : [string,number,boolean] = ['跳跳',520.123,true]
console.log(arr3[1].toFixed(2)); // 520.12 保留两位小数
function useFetch() {
const name: string = "跳跳";
const age: number = 18;
return [name, age] as const;
}
//这里如果不使用 as const 会发现 我们结构出来的数组类型是name: string | number
// 使用完 as const 以后 为string,as const 也叫类型断言
function useFetch2() {
const response: string = "Barry";
const age: number = 25;
return tuplify(response, age)
}
function tuplify<T extends unknown[]>(...elements: T): T {
return elements;
}
枚举允许开发者定义一组命名的常量。使用枚举可以使其更容易记录意图,或创建一组不同的情况。TypeScript提供了基于数字和字符串的枚举。
//数字枚举如果没有初始化,默认初始化值为0,每项+1
enum Direction {
Up, // 0
Down,// 1
Left,// 2
Right// 3
}
//如果有初始化或被赋值,则在初始化值的基础上,每项+1
enum Direction {
Up = 1,// 1
Down,// 2
Left,// 3
Right// 4
}
//如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点的,但建议尽量避免
enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 3); // true
console.log(Days["Wed"] === 3); // true
console.log(Days[3] === "Sun"); // false
console.log(Days[3] === "Wed"); // true
除了创建一个以属性名做为对象成员的对象之外,数字枚举成员(字符串枚举成员没有反向映射)还具有了 反向映射,从枚举值到枚举名字
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true
console.log(Days[0] === "Sun"); // true
console.log(Days[1] === "Mon"); // true
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
数字和字符串混用,不推荐!
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
//没有初始化器的枚举要么需要放在第一位,要么必须放在用数字常量或其他常量枚举成员初始化的数字枚举之后
//上述代码会报错,因为Red是计算项,而Green紧接其后却无法获取初始值
enum Color {Red = "red".length, Green, Blue};
常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员,假如包含了计算成员,则会在编译阶段报错
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
//编译为
var directions = [0 , 1, 2 , 3];
/**
* 用于定义一些带名字的常量
* 后台管理系统 下面用枚举定义一些角色类型
*/
enum role{
stu=1,//如果不加1 默认排序从0开始
teacher,
footer,
admin
}
//字符串枚举
enum message{
success="恭喜你,成功了",
fail="抱歉,失败了"
}
//异构枚举 有数字和字符串
enum Answer{
N,//数字 默认为0
Y="我是字符串"
}
as const 被称为 const 类型断言,const 类型断言告诉编译器,要将这个表达式推断为最具体的类型,如果不使用它的话,编译器会使用默认的类型推断行为,可能会把表达式推断为更通用的类型。
// 强制类型转换
function getLength(str: string | number): number {
if((<String>str).length)
// 或
if ((str as string).length) {
return (<String>str).length
} else {
return str.toString().length;
}
}