TS简单总结

12.typeof和keyof运算符

1.typeof
JavaScript ⾥⾯, typeof 运算符只可能返回⼋种结果,⽽且都是字符串。

typeof undefined; // "undefined"
typeof true; // "boolean"
typeof 1337; // "number"
typeof "foo"; // "string"
typeof {}; // "object"
typeof parseInt; // "function"
typeof Symbol(); // "symbol"
typeof 127n // "bigint

TypeScript 将 typeof 运算符移植到了类型运算,它的操作数依然是⼀个值,但是返回的不是字符串,⽽是该值的TypeScript 类型。

const a = { x: 0 };
type T0 = typeof a; // { x: number }
type T1 = typeof a.x; // number

ts中的typeof是 根据已有的值 来获取值的类型 来简化代码的书写

const myVariable = 42;
type MyVariableType = typeof myVariable; // MyVariableType 的值为 "number"

2.keyof
keyof运算符接受⼀个对象类型作为参数,返回该对象的所有键名组成的联合类型。
keyof 类型别名 keyof {}

练习

type Person={name:string,age:number}
type MyType=keyof Person //name|age
//type MyType=keyof {name:string,age:number} //name|age
let a:MyType="name"

13.映射类型

映射类型:基于旧类型创建新类型(对象类型),减少重复,提升开发效率。

映射类型只能在类型别名中使⽤,不能在接⼝中使⽤。
in后⾯跟的是联合类型,也可以是通过keyof⽣成的联合类型

//基本使⽤
type My="a"|"b"|"c"
type MyType={[key in My]:number} //{a:number,b:number,c:number}
//配合keyof使⽤
type Props={a:number,b:string,c:boolean}
type MyType={[key in keyof Props]:Props[key]} //{a:number,b:string,c:boolean}
//此时的key不是关键字,可以随便命名
let obj:MyType={a:123,b:"2",c:true}

配合可选属性使⽤

type My="a"|"b"|"c"
type MyType={[key in My]?:number} //{a?:number,b?:number,c?:number}
let obj:MyType={a:123}

配合只读属性使⽤

type My="a"|"b"|"c"
type MyType={readonly [key in My]:number} //{readonly a:number,readonly b:number,readonly c:number}
let obj:MyType={a:123,b:2,c:88}
obj.a=888 //报错

14.接⼝

1.基本使⽤
在 TypeScript 中,我们使⽤接⼝(Interfaces)来定义对象的类型。
我们之前定义对象类型都是 形如{name:string,age:number}这种形式
但是如果我的别的对象也是这种结构,我们不⾄于每个对象都重新声明⼀遍这个类型吧,所以就需要⽤到接⼝

接⼝其实就是相当于定义⼀个模板,以后声明的对象都得根据这个模板要求来

interface Person{
 name:string,
 age:number,
 salary:number
}
let obj:Person={name:"张三",age:18,salary:3500}

接⼝中同样⽀持只读属性,可选属性,任意属性

interface Person{
 name:string,
 age:number,
 readonly salary:number,
 like:string[],
 run?:()=>void,
 [propName:string]:string|number|string[]|(()=>void)//这个是任意属性
}
//propName代表属性名,肯定是字符串,propName只是形参,可以换成别的名字 任意属性只有⼀个没有多个,它代表了其他的所有属性
//任意属性的类型⼀定是其他类型(包含可选属性)的⽗类
//后续可以参考第七条下的第二条任意属性

2.接⼝的继承
如果你需要创建⼀个新的接⼝,⽽这个新的接⼝中的部分内容我已经在已存在的接⼝中定义过了,那么可以直接继承,⽆需重复定义

语法:

interface 接⼝名 extends 另⼀个接⼝名

只要存在接⼝的继承,那么我们实现接⼝的对象必须同时实现该接⼝以及他所继承的接⼝的所有属性

interface Person{
 name:string,
 age:number,
 address:string
}
interface Girl extends Person{
 height:number,
 hobby:string[]
}
interface Boy extends Person{
 salary:number,
 car:string
}
let xf:Girl={
 name:"⼩芳",
 age:18,
 address:"北京",
 height:170,
 hobby:["逛街","买买买"]
}

⼀个接⼝可以被多个接⼝继承,同样,⼀个接⼝也可以继承多个接⼝,多个接⼝⽤逗号隔开
继承多个接⼝,必须同时实现继承每⼀个接⼝定义的属性

interface Pro{
 phone:string,
 coat:string
}
interface Girl extends Person,Pro{
 height:number,
 hobby:string[]
}
interface Boy extends Person{
 salary:number,
 car:string
}
let xf:Girl={
 name:"⼩芳",
 age:18,
 address:"北京",
 height:170,
 hobby:["逛街","买买买"],
 phone:"华为",
 coat:"安踏"
}

多层继承:需要实现该接⼝以及所继承的接⼝和继承接⼝的接⼝
(就类似于子继承父,也要继承父级继承的爷爷的接口)

interface Person{
 name:string,
 age:number,
 address:string
}
interface Girl extends Person{
 height:number,
 hobby:string[]
}
interface Xh extends Girl{
 hair:string
}
let xh:Xh={hair:"红⾊",height:170,hobby:["买买买"],name:"⼩红",age:18,address:"北京"}

3.接⼝同名会合并
名字相同的接⼝不会冲突,,只要接口中的属性名不重复,就会合并为⼀个

interface Person{
 name:string,
 age:number,
 address:string
}
interface Person{
 salary:number
}
let xm:Person={name:"⼩明",age:17,address:"beijng",salary:3500}

4.接⼝中使⽤联合类型

interface Person{
 name:string,
 age:number,
 address:string
 hobby:string[]|(()=>void)
}

5.接⼝也可以⽤于定义数组
但是不推荐,定义数组还是优先使⽤我们之前讲的⽅式

interface MyArr{
 [index:number]:string
}
let arr:MyArr=["@","3"]

6.接⼝也可以定义函数

interface MyArr{
 (a:number):number
}
let fn:MyArr=function(a:number){return 123}

7.接⼝和类型别名的区别

  • interface 与 type 的区别有下⾯⼏点。
    (1) type 能够表示⾮对象类型,⽽ interface 只能表示对象类型(包括数组、函数等)。
    (2) interface 可以继承其他类型, type 不⽀持继承。
    (3)同名 interface 会⾃动合并,同名 type 则会报错
    (4) interface 不能包含属性映射(mapping), type 可以
interface Point {
x: number;
y: number;
}
// 正确
type PointCopy1 = {
[Key in keyof Point]: Point[Key];
};
// 报错
interface PointCopy2 {
[Key in keyof Point]: Point[Key];
};

15.交叉类型

交叉类型(Intersection Types)⽤于组合多个类型,⽣成⼀个包含所有类型特性的新类型。可以
理解为将多个类型合并为⼀个更⼤的类型,新类型拥有所有原始类型的成员。使⽤ & 符号表示交
叉类型。

type Person={name:string,age:number}
type Emp={salary:number,address:string}
type C=Person&Emp&{height:number}
let obj:C={name:"张三",age:18,salary:3500,address:"beijing",height:180}

注意不要对基本类型使⽤,只能对对象类型使⽤

type C=string&number

16.类型断⾔

1.基本⽤法
类型断⾔就是我明确的知道我这个数据肯定是字符串,告诉编译器你不⽤检测他了。
语法:

as 类型
//或者
<类型>/*
在 tsx 语法(React 的 jsx 语法的 ts 版)中必须使⽤前者,即 值 as 类型。
形如 <Foo> 的语法在 tsx 中表示的是⼀个 ReactNode,在 ts 中除了表示类型断⾔之外,也可能是表示
⼀个泛型。
故建议⼤家在使⽤类型断⾔时,统⼀使⽤ 值 as 类型 这样的语法
*/

2…将⼀个联合类型断⾔为其中⼀个类型
当 TypeScript 不确定⼀个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型
中共有的属性或⽅法

// type C=string|number
function fn(m:string|number){
 (m as string).substring(1)
}
fn(100)//错误

注意:类型断⾔只能欺骗ts编译器,让他不报错,⽆法避免项⽬运⾏时的错误,所以使⽤断⾔要谨慎

interface Boy{
 name:string,
 make:()=>number
 }
 interface Girl{
 name:string,
 cost:()=>void
}
function fn(obj:Boy|Girl){
 (obj as Boy).make()
}

案例

let student={} as {name:string}
student.name="张三"

3.将任何⼀个类型断⾔为any

let num:number=1;
console.log((num as any).length)

4.将any断⾔为任意类型

let a:any=5;
console.log((a as number).length) //报错

5.将⽗类断⾔为⼦类

class Students{
 make(){
 console.log("make")
 }
}
class Xm extends Students{
 run(){
 console.log("run")
 }
}
let a=new Students();
(a as Xm).run() //编译通过,运⾏报错

6.⾮空断⾔ !

type MyFn=()=>number
function fn(m:MyFn | undefined){
 let num=m!()
 let num2=m()//错误写法
}

7.双重断⾔ (不推荐使⽤)

interface Girl{
 name:string,
 cost:()=>void
}
interface Boy{
 name:string,
 make:()=>void
}
function fn(obj:Girl){
 obj as any as Boy
}
  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Vue 项目中使用 TypeScript,可以通过配置 TSLint 来进行代码规范和类型检查。以下是一些设置 TSLint 的经验总结: 1. 安装依赖 ``` npm install --save-dev tslint tslint-config-prettier tslint-plugin-prettier tslint-eslint-rules typescript ``` 2. 配置 TSLint 在项目根目录下创建 tslint.json 文件,并添加以下内容: ``` { "extends": [ "tslint:recommended", "tslint-config-prettier" ], "rules": { "interface-name": false, "no-console": false, "no-empty": false, "no-unused-expression": false, "no-unused-variable": false, "semicolon": [true, "always"] }, "linterOptions": { "exclude": [ "node_modules/**", "dist/**" ] } } ``` 以上配置文件的含义: - extends:继承的规则,包含了 TSLint 推荐的规则和 Prettier 的规则。 - rules:自定义的规则,可以根据团队的需求进行配置。 - linterOptions:指定需要忽略的文件或目录。 3. 配置 VS Code 在 VS Code 中安装以下插件: - TSLint - Prettier - Code formatter 然后在项目根目录下创建 .prettierrc 文件,并添加以下内容: ``` { "singleQuote": true, "trailingComma": "es5", "semi": true, "tabWidth": 2 } ``` 最后,在 VS Code 的设置中添加以下配置: ``` { "editor.formatOnSave": true, "vetur.validation.template": false, "prettier.eslintIntegration": true, "eslint.validate": [ "javascript", "javascriptreact", "vue", "typescript" ], "typescript.validate.enable": false, "tslint.enable": true } ``` 以上配置的含义: - editor.formatOnSave:在保存时自动格式化代码。 - vetur.validation.template:禁止 Vetur 对模板的验证,因为它可能与 TSLint 发生冲突。 - prettier.eslintIntegration:启用 Prettier 和 ESLint 的集成。 - eslint.validate:指定需要验证的文件类型。 - typescript.validate.enable:禁止 VS Code 内置的 TypeScript 验证器,因为它可能与 TSLint 发生冲突。 - tslint.enable:启用 TSLint 验证器。 4. 迁移经验 如果是一个已经存在的 Vue 项目,需要将 JavaScript 代码迁移到 TypeScript,可以按照以下步骤进行: - 安装 TypeScript 和 @types/node - 将 .js 文件改名为 .ts 文件,并修改文件中的代码 - 在 Vue 组件中添加 <script lang="ts"> 标签,并将代码移到其中 - 逐步修改代码,添加类型注解和接口定义 需要注意的是,迁移过程中可能会遇到一些问题,例如: - 无法识别某些模块,需要在 tsconfig.json 中配置 paths - 需要安装额外的类型声明文件,例如 @types/vue、@types/lodash 等 - 一些 JavaScript 的语法不支持 TypeScript,需要进行调整 总之,迁移过程需要耐心和谨慎,可以先从一些简单的模块开始,逐步迁移。同时,使用 TSLint 和 VS Code 可以帮助我们更方便地进行代码规范和类型检查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值