ts与js的区别,优势是什么?
- ts是js的超集,超集就是父级,ts = js + type
- 浏览器 nodejs可以直接执行js, 但是不能直接执行ts
- 编译层面, ts有编译阶段,js没有编译阶段,编译就是从A语言编程B语言的过程
- 编写层面, ts更难写一点,但是类型更安全,bug会更少
- 文档层面,ts的代码写出来就是文档,IDE可以完美提示
any unknow never的区别是什么?
- any: 任意类型
- unknow: 不确定是什么类型, 值可能是从ajax获取到的。
type D = {name:string}
let b: unknow = JSON.parse('{'name': 'frank'}')
console.log((b as D).name)
使用b之前断言一下他的类型是B 这样就不会报错
- any和 unknow 二者都是顶级类型,任何类型的值都可以赋值给顶级类型变量,所以在赋值的时候,任何值都可以赋值给顶级类型,都不会报错
- void 函数不要返回值
let foo:any = 123; //不报错
let bar: unknow = 123; //不报错
但是unknow比any的类型检查更严格,any什么检查都不做,unknow要求先收窄类型。如果把unknow类型的值赋值给一个string类型的变量,就会报错
const value: unknow = 'hello world';
const someString:string = value; //会报错, Type 'unknow' is not assignable to type 'string'
const value: unknow = 'hello world'
const someString: string = value as string; //不报错
如果改成any,基本在哪都不报错,所以能用unknow就优先用unknow,类型更安全一点
- never 是底类型,不应该出现的类型。
type x = number & string; //这里x的类型就是never了。 一旦代码中出现了类型是never的话,那说明是代码哪里出错了
- 元组 比如你想写一个数值数组,可能是这样写
let p:Array<number> = [1,2,3]
但是如果想要固定数组的长度呢?可以这样写
let p: [number, number] = [1,2]
let p: [number, number] = [1,2,3] //报错,因为长度应该为2,但是现在是3个
上面的就是元组,需要把每个元素的类型都确定下来。这个只是ts里面的概念,js中是没有的。
- 枚举
eum Dir {东,南,西,北}
let p:Dir = Dir.东
type和interface的区别
- 组合方式,interface使用extends来实现继承,type使用&来实现联合类型
- 扩展方式,interface可以重复声明用来扩展,type一个类型只能声明一次
- 范围不同,type适用于基本类型,interface一般不行
- 命名方式,interface会创建新的类型名,type只是创建类型别名,并没有创建类型。
类型断言
interface Person {
name: string;
age: number;
}
function getPerson(config: Person): { personDetail: string } {
return {personDetail: config.name}
}
getPerson({name: 'xiaoming'} as Person) //虽然少了age参数但是也不会报错
添加字符串索引签名
如果发现可能带有任意数量的其他属性,我们可以这样定义
interface Person {
name: string;
[propName:string]:any; //主要是这里
}
function getPerson(config: Person):{personDetail: string} {
return { personDetail: config.name }
}
getPerson({name: 'xiaoming', age: 34, color: 'yellow' });
函数类型
对函数的参数以及返回值进行定义
interface SearchFun {
(keyword: string): {res: number[]}
}
let getSearchRes: SearchFun;
getSearchRes = function (keyword: string): { res: number[] } {
return { res: [1, 2, 3] };
}
getSearchRes('333');
对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配, 但是对应位置上的参数类型必须是兼容的。