// 创建泛型函数:
// 1.语法:在函数名称的后面添加<>(尖括号),尖括号中添加类型变量,比如此处的Type。
// 2.类型变量 Type,是一种特殊类型的变量,它处理类型而不是值。
// 3.该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)
// 4.因为 Type 是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型
// 5.类型变量 Type,可以是任意合法的变量名称
function aFn<Type>(value: Type): Type {
return value
}
console.log(aFn<string>('55')) // string 类型
console.log(aFn<number>(555)) // number 类型
// 简化调用泛型函数
// 1.在调用泛型函数时,可以省略<类型>来简化泛型函数的调用
// 2.此时,TS 内部会采用一种叫做类型参数推断的机制,来根据传入的实参自动推断出类型变量Type 的类型
// 3.比如,传入实参10,TS 会自动推断出变量num 的类型number,并作为 Type 的类型。
aFn(10)
// 泛型约束:
// 默认情况下,泛型函数的类型变量Type 可以代表多个类型,这导致无法访问任何属性。比如,id('a')调用函数时获取参数的长度:
function bFn<T>(value: T): T {
console.log(value.length) // 参数可多种类型 有这里如果是数字类型会报错
return value
}
bFn(555)
// 添加泛型约束收缩类型,主要有以下两种方式:1指定更加具体的类型2添加约束
function cFn<T>(value: T[]): T[] { // 指定更加具体的类型
console.log(value.length)
return value
}
cFn('444') // 报错 因为我们上面指定了是[]
cFn([]) // 没报错
// extends 添加约束
interface ILength {length: number}
function dFn<T extends ILength>(value: T): T { // 这里的 extends 不是继承 是 传入的类型参数一定要length 属性
console.log(value.length)
return value
}
dFn(555) //类型“number”的参数不能赋给类型“ILength”的参数
dFn('555') // string 有lenght属性 ∴没报错
dFn([]) // array 有lenght属性 ∴没报错
function getProp<T, K extends keyof T>(obj: T, key: K): void{
console.log(obj[key])
}
interface ObjType {age: number, name: string}
const Obj = {age: 66, name: 'james'}
getProp<ObjType, 'age'>(Obj, 'age') // 第二个参数只能 Obj的key
getProp<ObjType, 'name'>(Obj, 'name')
getProp<ObjType, 'name3'>(Obj, 'name3') // 报错
interface Atype<T> {
id: (n: T) => T
ids: (n: T) => T[]
}
// 用的时候要指定 某个类型 不能没有
const obj:Atype<number> = {
id(n){
return n
},
ids(n){ return [n] }
}
console.log(obj.id(5))
console.log(obj.ids(5))
const obj2:Atype<string> = {
id(n){
return n
},
ids(n){ return [n] }
}
console.log(obj2.id('5'))
console.log(obj2.ids('5'))
class Geral<T> {
defaultValue: T
constructor(val: T) {
this.defaultValue = val
}
add(val: T): T {
this.defaultValue = val
return val
}
}
const geral = new Geral<number>(6)
console.log(geral)
geral.add('666') // 这里也可能传number 因为在实例的时候已经指定了number类型的
const geral2 = new Geral(6) // 也可以不用指定具体的类型 里面 constructor 有做赋值 TS会自动推断 constructor Geral<number>(val: number): Geral<number>
interface Props {
id: number,
name: string
}
type Props2 = Partial<Props> // 把接口传进去 会实现出所有的属性为可选的 类型出来 type Props2 = { id?: number | undefined;name?: string | undefined;}
let aObj: Props = { // 类型 "{ id: number; }" 中缺少属性 "name",但类型 "Props" 中需要该属性
id: 5555
}
let bObj: Props2 = { // 没有报错
id: 5555
}
console.log(aObj,bObj)
interface Props {
id: number,
name: string
}
type Props2 = Readonly<Props> // 实例出来新的类型里面的属性都为只读
let obj:Props2 = {
id: 666,
name: 'james'
}
obj.id = 666 // 无法为“id”赋值,因为它是只读属性
interface Props {
id: number,
name: string
}
type Props2 = Pick<Props, 'id'> // 实例出来新的类型 type Props2 = {id: number;}
let obj:Props2 = {id: 5555, name: '666'} // 对象字面量只能指定已知属性,并且“name”不在类型“Props2”中
type Atype = Record<'aa' | 'bb', string> // 相当于 type Atype = {aa: string; bb: string;}
let obj:Atype = {
aa: '555',
bb: '55'
}
interface AnyType {
[key: string]: number
}
const obj: AnyType = {
id: 5555,
aaa: 9999,
bbb: '555' // 报错 不能将类型“string”分配给类型“number”
}
console.log(obj)
interface ArryType<T> {
[n: number]: T
}
const arr: ArryType<number> = [0, 1, 2]
console.log(arr)
type KeyType = 'aaa' | 'bbb' | 'ccc'
type KeyType2 = {
ddd: number
fff: number
}
type PorpType = { [key in KeyType] : number } // 循环 KeyType type PorpType = { aaa: number;bbb: number;ccc: number;}
type PorpType2 = { [key in KeyType2] : number } // 不能循环 KeyType2 不能将类型“KeyType2”分配给类型“string | number | symbol”
const obj:PorpType = {
aaa: 5,
bbb: 5,
ccc: 5,
}
console.log(obj)
type KeyType = {
ddd: number
fff: number
}
type PorpType = { [key in keyof KeyType] : number } // keyof 把 KeyType 变成 'ddd' | 'fff' 才能被in循环
const obj:PorpType = {
ddd: 5,
fff: 5
}
console.log(obj)
type KeyType = {
ddd: number
fff: string
}
type PorpType = KeyType['ddd'] // 访问KeyType ddd 类似于对象访问 type PorpType = number
// 多个属性名
type PorpType2 = KeyType['ddd' | 'fff'] // 访问KeyType ddd 类似于对象访问 type PorpType = number | string
// 使用keyof
type PorpType3 = KeyType[keyof KeyType] // type PorpType3 = string | number