泛型
泛的意思是:漂浮, 比如泛舟; 泛型: 类型漂浮未定 => 动态类型. 用于: 函数 接口 类
T extends string | number 泛型约束
function a<T = any, K> (: number, value: T) { // 泛型参数设置默认值any
const arr = Array<T>(l).fill(value) // ['foo', 'foo', 'foo]
}
const res = a<string>(3, 'foo');// 使用的时候再传入类型, 也可不传, ts编译器做类型推论
function getLength<T extends string | any[]>(a: T): number{
return a.length
}
interface iLength
T extends iLength
泛型工具类
let obj: Partial<T> =
函数
- 函数参数可以设置默认值是es6语法, 可选值 ? 是ts语法
- 函数有了默认值, 就不能设置可选了. 设置了可选也不能设置默认值.
function fn(x = 'zml',y?){ // 编译成 js 就没有?了
console.log(x,y)
}
fn() // zml undefined
fn('ymy',1) // ymy 1
function sum(x: number, y?: number, ...res: number[]): number {
return x + y;
}
// 函数表达式
let mySum: (x: number, y: number) => number = function () {}
let mySum = function(x: number, y:number):number{ // 前后都限定感觉麻烦, 倾向于这样写.
}
//
函数重载的意思是, 重新传不同类型的参数, java里面两个同名函数, 传参类型不同, 就是重载 js 本身是没函数重载的
function reverse(x: number): number;
function reverse(x: string): string;
function revsrse(x: number | string): number | string {
if(typeof x === 'number') {
return Number(String(x).split('').reverse().join(''))
} else if(typeof x === 'string) {
return x.split('').reverse().join('')
}
}
let a: (a:string,b:number) => boolean= (c, b) => {
return c.length > b ? true : false
}
a('abc', 2)
ts 的函数表达式的写法觉得好冗余, 就像下面这种
let a:(e:string, f:number)=>boolean = (a: string, b: number): boolean => {
return a.length > b ? true : false
}
interface Crazy {
new(): { // 这种怎么理解,new执行是这个
hello: number;
};
}
class CrazyClass implements Crazy {
constructor() {
return { hello: 123 };
}
}
// Because
const crazy = new CrazyClass(); // crazy would be { hello:123 }
console.log(crazy)
泛型接口函数
interface GenericIdentityFn {
<T>(arg: T): T;
}
let g:GenericIdentityFn = function<T>(b: T):T {
return b
} // 实现接口
interface GenericIdentityFn<T, K> {
(arg: T): T
commonets: K[]
}
接口可以多继承, 同样接口也可以多合并, 也就是写多个名字
interface iPerson extends iPerson2, iPerson3 {
name: string
}
interface iPerson2{
age: number
}
interface iPerson3{
gender: 'male' | 'female'
}
let p:iPerson = {
name: 'mingle',
age: 34,
gender:'male'
}
搭配axios
// 请求接口数据
interface ResponseData<T> {
code: number;
result: T[] | null; // Array<T>
}
let a: ResponseData<string> = {
code: 1,
result: ['a'],
}
let b: ResponseData<null> = {
code: 1,
result: null
}
// 在 axios.ts 文件中对 axios 进行了处理,例如添加通用配置、拦截器等
import Ax from './axios';
import { ResponseData } from './interface.ts';
export function getUser<T>() {
return Ax.get<ResponseData<T>>('/somepath') // ??
.then(res => res.data)
.catch(err => console.error(err));
}
const obj: { name: string } = { name: 'zhangmingle' } // 有了这种内联注解, 为什么还要用接口?
接口用来约定对象的结构. 不用逗号,分号
interface Person { 有的建议加I 为啥不加小写i???
readonly id: number 只读
age?: number 可选
[prop : string]: any 可以添加任意数量的其它属性了, 类的话不用添加, 也能自己扩展 其他的类型需要是它的子集
run(): void
mover():void
}
interface A{
name: string
}
interface A{
age: 12
} // 声明合并
class Person implements A { // 类实现接口,可增加
}
class A implements B,C{} // 可多个
class P<T>{
name: T;
constructor(name: T) {}
}
接口和type类似, 不同的是接口还可以限制类.
有必要用接口数组?
interface iPerson {
[i: number]: string
}
let man: iPerson = ['s', '']
接口继承和接口合并有啥区别- 没啥区别
- 写两个同名的接口会合并??
接口限制的比较严格啊
参考
深入理解typescript
2022年了,我才开始学 typescript ,晚吗?
typescript中文网
深入理解typescript
ts中的泛型与axios的一次相遇