目录
3.如何基于一个已有类型,扩展出一个大部分内容相似,但是有部分区别的类型?
官方写的是,TypeScript是JS类型的超集,它可以编译成纯JavaScript。TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。
支持ECMAScript6标准。
TS编译流程图
基本概念:TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式
基础类型:number、string、boolean、array、object、undefined、void
Any Void Null 和 Undefined Never Object
类型推论
可赋值性:数组、布尔、数字、对象、函数、类、字符串、字面量,满足以下任一条件时,A类型可以赋值给B类型
- A是B的子类型
- A是any类型
基础类型&高级类型使用
- enum:枚举
- type,interface
- 联合类型 |(联合类型一次只能一种类型;而交叉类型每次都是多个类型的合并类型)
- 交叉类型 & (联合类型一次只能一种类型;而交叉类型每次都是多个类型的合并类型)
- typeof: 可以用来获取一个变量声明或对象的类型
function toArray(x: number): Array<number> { return [x]; } type Func = typeof toArray; // -> (x: number) => number[]
- keyof:可以用来一个对象中所有的key值
interface Person { name: string; age: number; } type K1 = keyof Person; // "name" | "age"
- in:用来遍历枚举类型
type Keys = "a" | "b" | "c" type Obj = { [p in Keys]: any } // -> { a: any, b: any, c: any }
- extends
有时候我们定义的泛型不想过于灵活或者说想继承某些类等,可以通过extends关键字添加泛型约束。interface ILengthwise { length: number; } function loggingIdentity<T extends ILengthwise>(arg: T): T { console.log(arg.length); return arg; } loggingIdentity(3); loggingIdentity({length: 10, value: 3});
-
Partial<Type>
Partial<T> 的作用就是将某个类型里的属性全部变为可选的类型 ?。interface Props { a: number; b: string; } const obj: Props = { a: 6 } // obj报错: 类型 "{ a: number; }" 中缺少属性 "b",但类型 "Props" 中需要该属性。 const obj2: Partial<Props> = { a: 6 }; // 不会报错 const obj3: Partial<Props> = {}; // 不会报错
-
Required<Type>
Required<T> 的作用就是将某个类型里的属性全部变为必选的类型。interface Props { a?: number; b?: string; } const obj: Props = { a: 6 }; const obj2: Required<Props> = { a: 6 } // obj2报错:类型 "{ a: number; }" 中缺少属性 "b",但类型 "Required<Props>" 中需要该属性。 const obj3: Required<Props> = { a: 6, b: 'b' }; //正确写法
-
Readonly<Type>
Readonly<T> 的作用是将某个类型所有属性变为只读属性,也就意味着这些属性不能被重新赋值。interface Todo { title: string; } const todo: Readonly<Todo> = { title: 'Hello' } todo.title = 'Word'; // title 报错:无法分配到 "title" ,因为它是只读属性。
-
Record
Record<K extends keyof any, T> 的作用是将 K 中所有的属性的值转化为 T 类型。interface PageInfo { title: string; } type Page = "home" | "about" | "contact"; const x: Record<Page, PageInfo> = { about: { title: "about" }, contact: { title: "contact" }, home: { title: "home" } };
-
Pick<Type, Keys>
通过从中选择一组属性Keys
(字符串文字或字符串文字的并集)来构造类型Type
。interface Todo { title: string; desc: string; test: boolean; } type TodoPreview = Pick<Todo, 'title' | 'test'>; const todo: TodoPreview = { title: 'hello', test: false, } todo; // const todo: TodoPreview
-
Omit<Type, Keys>
通过从中选择所有属性Type
然后删除Keys
(字符串文字或字符串文字的联合)来构造类型。interface Todo { title: string; desc: string; test: boolean; createdTime: number; } type TodoPreview = Omit<Todo, 'createdTime'>; const todo: TodoPreview = { title: 'Hello', desc: 'Word', test: false, } todo; // const todo: TodoPreview type TodoInfo = Omit<Todo, 'desc' | 'createdTime'>; const todoInfo: TodoInfo = { title: 'Hello', test: true } todoInfo; // const todoInfo: TodoInfo
-
Exclude
Exclude<T, U> 的作用是将某个类型中属于另一个的类型移除掉。type T0 = Exclude<"a" | "b" | "c", "a">; // type T0 = 'b' | c' type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // type T1 = 'C' type T2 = Exclude<string | number | (() => void), Funciton>; // type T2 = string | number;
-
Extract
Extract<T, U> 的作用是从 T 中提取出 U。type T0 = Extract<"a" | "b" | "c", "a" | "f">; // type T0 = 'a'; type T1 = Extract<string | number | (() => void), Function>; // type T1 = () => viod;
常见问题
1. ts的好处是什么?
-
TypeScript是JavaScript的加强版,它给JavaScript添加了可选的静态类型和基于类的面向对象编程,它拓展了JavaScript的语法。所以ts的功能比js只多不少.
-
Typescript 是纯面向对象的编程语言,包含类和接口的概念.
-
TS 在开发时就能给出编译错误, 而 JS 错误则需要在运行时才能暴露。
-
作为强类型语言,你可以明确知道数据的类型。代码可读性极强,几乎每个人都能理解。
-
ts中有很多很方便的特性, 比如枚举值
2. type 和 interface的异同
重点:interface侧重于描述数据结构,type(类型别名)侧重于描述类型。
异同点:
- 都可以描述一个对象或者函数
interface User { name: string age: number } interface SetUser { (name: string, age: number): void; } type User = { name: string age: number }; type SetUser = (name: string, age: number)=> void;
- 都允许拓展(extends)
interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type,type 也可以 extends interface。虽然效果差不多,但是两者语法不同。// interface extends interface interface Name { name: string; } interface User extends Name { age: number; } // type extends type type Name = { name: string; } type User = Name & { age: number }; // interface extends type type Name = { name: string; } interface User extends Name { age: number; } // type extends interface interface Name { name: string; } type User = Name & { age: number; }
-
只有 type可以做的
(1)type 可以声明基本类型别名,联合类型,元祖等类型// 基本类型别名 type Name = String interface Dog { wong(); } interface Cat { miao(); } // union(联合类型) type Pet = Dog | Cat // tuplle(元组) 具体定义数组每个位置的类型 type PetList = [Dog, Pet] // 当你想获取一个变量的类型时,typeof 的返回值 let div = document.createElement('div'); type B = typeof div
(2)type 能使用 in 关键字生成映射类型,但 interface 不行type Keys = 'firstname' | 'surname'; type DudeType = { [key in Keys]: String; }; const test: DudeType = { fitstname: 'Li', surname: 'Zhang' };
-
只有interface可以做的
interface 可以多次定义 并被视为合并所有声明成员,type不支持interface Point { x: number; } interface Point { y: number; } /* Point的接口为: * { x: Number, y: Number }; */ const point: Point = { x: 1, y: 2 };
3.如何基于一个已有类型,扩展出一个大部分内容相似,但是有部分区别的类型?
可以通过Pick和Omit
interface Test {
name: string;
sex: number;
height: string;
}
type Sex = Pick<Test, 'sex'>;
const a: Sex = { sex: 1 };
type WithoutSex = Omit<Test, 'sex'>;
const b: WithoutSex = { name: '1111', height: 'sss' };
比如Partial,Required。再者可以通过泛型。
4.什么是泛型,泛型的具体使用?
泛型是指在定义函数、接口或类的时候,不预定指定具体的类型,使用时再去指定类型的一种特性。
可以把泛型理解为代表类型的参数。
interface Test<T = any> {
userId: T;
}
type TestA = Test<string>;
type TestB = Test<number>;
const a: TestA = {
userId: '111',
};
const b: TestB = {
userId: 2222,
};