1.Ts的数据类型
*js基本数据类型:number、string、boolen、undefined、null、symbol
ts就是js的基础数据类型
例如:let a:sting=”ab”
ts中的function a():void{} 多了一个返回为空
*类型断言(补)
let str:any = 'it666';
let len = (str as string).length;
*类型断言就是告诉编译器, 你不要帮我们检查了, 相信我,它就是这个类型
*非原始类型 object Object {}
*object(常用)
let obj:object={a:1};
let arr:object=[1];
let obj1:object=1 ///报错
object 不包含基础数据类型
*Object
let obj:Object={a:1};
let arr:Object=[1];
let obj1:Object=1 ///不报错
*{}
同上
2.Ts的数组类型
*数据元素一般数据类型都一致,便于处理
let arr:number[]=[1,2,3];
*泛型写法
let arr:Array<number>=[1,2,3];
*元祖
let arr: [number,number,boolen]=[1,2,true]
3.Ts的联合类型
*类似于或者
let a:number|string=10(“10”)
*两边都是常量,就是必须是其中一个
*两遍都是对象,就是必须是其中一个或者两个都有,不可以有其他的对象
4.Ts的交叉类型
& 一般针对对象,就是必须两边都有
5.any 和 unkown 类型
*any :一般不推荐使用,相当于在写js,就是不规定他的类型,绕过ts类型检验
*unkown :一开始设为不知道,赋值之后就会给他类型,会有ts的类型校验
用法if(type of n ==== “number”){
n.toFixed(2)
}else if(type of n ==== “string”){
n.Substring()....
}
6.接口类型interface
*接口interface是用来自定义类型的
*定义接口---给对象用
interface Imy{
readonly name:string;
age?:number;
//?代表属性可以缺省,readonly代表只读,修改就会报错
}
let obj : Imy;
obj={
name:”gg”,
age:7
}
*定义接口类型---给数组用
interface Iarr{
// [idx:number]下标类型:值类型
[idx:number]:number | string
}
let arr:Iarr=[1,2,3,”4”]
*定义接口类型---给函数用
interface Ifun{
(p:string,a:number):void;
}
let Fn:Ifun=(p:string,a:number)=>{
}
fn(“”,1)
*接口的继承:extends关键字,类似class,继承的定义类型必须全部包括;如果同名 interface,则是合并,不是js的以下面的作为最后的定义
7.联合交叉类型
*let obj:{name:string}&{age:number}|{name:number}&{age:string},代表要么属于左边要么 等于右边
8.类型别名 type
*type StrorNum=string|number; let st:StrorNum=1//可以是string或者number
*type objType={a:number&2,b:string};let obj:objType={a:2,b:”bbb”}
***interface和type的区别:
*都可以用来自定义类型 *类型别名支持联合和交叉类型 *类型别名不支持重复定 义,接口可以;个人觉得type是把定义的样子写一遍,interface是定义类型框架样 子
*混用:
interface AItf{
a:string
}
//用类型别名来保存接口上的某个属性类型
type Atype=AItf[“a”]
let str:Atype=”10”
9.Ts函数
*基本用法:funtion fn(a:number,b:number):number{return a+b};
*接口定义函数类型
interface Ifn{
(p:string):number
}
let fn:Ifn=(p:string)=>{
return 1
}
*类型别名定义函数类型
type FnType=(p:string)=>void;
let fn2:Fntype=(p:string):void=>{}
*如果是一个对象里面有个fn,如果用interface需要定义一个外部obj,一个定义内部 fn
10.Ts函数参数
*默认值 funtion fn(a:number=1){return a+1}
*缺省参数 function fn(a?:number){return a+1}
*剩余参数 function fn(a:number,b:number,...arr[]){console.log(arr)} fn(1,2,3,4,5)
11.Ts中的promise
//定义接口中data属性的格式
interface DataItf{
a:number,
b:number
}
interface Result{
code:number,
data:DataItf[],//{a:number,b:number}[]
message:string
}
//promise对象: p对象名:Promise<res类型>
let p:Promise<Result>=new Promise((res,rej)=>{
res({
code:0,
data:[{a:1,b:2},{a:11,b:22}];
message:””
})
});
p.then(res=>{
//只有上述的定义,res才会不报错正常显示类型
if(res.code==0){
res.data.map(item=>item.a)
}
})
12.Ts的this指向window
interface Window{name:string;//Person:(n:string)=>void}//这边运用的interface的扩展特性(不会覆盖)
function Person(this:window,name:string){this.name=name}//js中默认window但是js需要指定;这个定义interface window在全局,如果用接口定义函数类型,定义的参数忽略this:window,直接interface{Person:(n:string)=>void;....}
13.this指向自定义对象
*这边使用type或者接口都可以
type ObjType={name:string,Person:(m:string)=>void}
let obj:objType={
name:”ge”,
Person:()=>{}
}
function Person(this:ObjType,name:string){
this.name=name;
}
obj.Person=Person;
*了解,指向多个类型function Person(this:ObjType | Window,name:string)...
14.枚举
*枚举不是类型,是用来列举数据的,用法例如
enum statusCode{
success=200,
paramsError=400
}
let code:string|number=200
if(code===statusCode.success){.....}
15.泛型基本用法
*遇到问题的场景
function fn(n:number|boolean):number|boolean{
return n
}
fn(100);
fn(true);
//不知道传入参数类型,如果写死定义,每次多个类型就要加一个
*泛型(类型参数化)解决 T只是个类似形参的标识符,用什么都行
function fn1<T>(n:T):T{
return n
}
fn1<number>(100);
fn1<boolean>(true);
*传入多个参数function fn1<T,G>(n:T,m:G):T{....
fn1<number,string>(100,”1”);
fn1<boolean,string>(true,”1”)
16.泛型在type和interface中的使用
*泛型-类型别名
type StrOrNum=string | number
//原type ObjType={name:string,getName:()=>string};
type ObjType<N,G>={name:N,getName:()=>G}
let obj:ObjType<StrOrNum,StrOrNum>={
name:23,
getName(){
return 1
}
}
//由此可见泛型不仅可以用T等类似形参,也可以定义形参的类型
*泛型-接口
//原interface Iperson={name:string;getName:()=>string};
interface Iperson<N,G>={name:N;getName:()=>G}
let obj:Iperson<StrOrNum,number>={
name:23,
getName(){
return 1
}
}
17.泛型约束-extends
type StrOrNum=string | number
interface PersonItf<N extends StrOrNum,G>{
Name:N;//需求:N只接受字符串或者数字
getName:()=>G
}
let obj:PersonItf<number,number>={
name:1,
getName(){
return 1
}
}
18.类(构造函数)
class Person{
public readonly name:string,
static title:string=”title的值”
constructor(n:string){
this.name=n
}
getName(){
return this.name
}
}
*定义类时候,相当于定义了同类型的interface
*类的继承
class Male extends Person{
custructor(name:string){
super(name)
}
}
*类的修饰符
针对类属性添加权限类似的功能
public:在类的 内部或者外部都可以访问
protected:类里面或者子类都可以访问
private:私有,只能在本类访问,哪怕子类都不行
readonly
*静态属性
static :只服务于类,new之后无法用Person.title=”22”
*抽象类和接口(后续补充,直接参考es6)
19.工具类-Partial(部分的)
interface PItf{
name:string,
age?:number
}
let obj:PItf={name:string};
*问题如果建一个let obj<PItf>={name:string},因为age没写就会报错,如果给age加?
这样只是第二个叫什么,但是如果又改呢怎么解决?
let obj:Partial<PItf>={name:string};
*作用:把<>里面的这个接口类型的属性设为可以缺省的
20.工具类-Required(部分的)
*还是用上面的例子let obj:Required<PItf>={name:string};意思就是即使接口用了?
*作用:把<>里面的这个接口类型的属性设为不可缺省的
21.keyof和in
*key
interface Person{
name:string;
age:number;
[idx:number]:number|string;
[idx:string]:string|number;
}
//keyof后面一般跟接口,表示接口的这些属性之一
type Ptype=keyof Person;
let p1:Ptype;//”name”|”age”|number|string
p1=”name”;
p1=”age”;
p1=1;
p1=”123”;
*in
type StrOrNum=string | number
type PItf={
[key in StrOrNum]:string
}
let obj:PItf={
a:””,
10:””
}
*typeof 提取变量类型
let str =”1230”;
type StrType=typeof str
let aaa:StrType=”xx”;
object同理