【TypeScript 4.5】007
【TypeScript 4.5】007
1、概述
我们可以通过各种类型操作符
用一种简洁的、可维护的方式表达复杂的操作和值
2、方法
泛型类型、keyof 类型操作符、typeof 类型操作符、索引访问类型、条件类型、映射类型、模板字面量类型
1、概述
软件工程的一个主要部分是建立组件
它们不仅有定义明确和一致的 api
还可以重复使用
这些组件为大型行项目提供灵活的能力
泛型是创建组件的重要工具
2、HelloWorld 演示
代码示例一
代码语言:javascript代码运行次数:0运行复制问题:只能返回 number 类型!
function identity(arg: number): number {
return arg
}
代码示例二
代码语言:javascript代码运行次数:0运行复制问题:失去了使用类型的意义!
function identity(arg: any): any {
return arg
}
代码示例三
代码语言:javascript代码运行次数:0运行复制完美,与代码示例一类型精确度一样!
function identity<T>(arg: T): T {
return arg
}
两种调用泛型的方式
代码语言:javascript代码运行次数:0运行复制// 方式一:传入类型
let a = identity<string>("hello world")
// 方式二:自动推断
let b = identity("hello world")
1、发现问题
代码语言:javascript代码运行次数:0运行复制function loggingIdentity<T>(arg: T): T {
cole.log(arg.length) // 报错:类型“T”上不存在属性“length”。
return arg;
}
2、解决问题
代码语言:javascript代码运行次数:0运行复制定义成数组
function loggingIdentity<T>(arg: Array<T>): T[] {
cole.log(arg.length)
return arg;
}
1、概述
说明
如何通过给一个变量设置这个函数的泛型类型
就需要使用泛型类型或泛型接口
代码示例
代码语言:javascript代码运行次数:0运行复制interface GenericIdentityFn {
<T>(arg: T): T
}
2、代码演示
泛型类型
代码语言:javascript代码运行次数:0运行复制function identity<T>(arg: T): T {
return arg
}
// 写法一
let a: <T>(arg: T) => T = identity
// 写法二
let b: { <T>(arg: T): T } = identity
泛型接口
代码语言:javascript代码运行次数:0运行复制function identity<T>(arg: T): T {
return arg
}
interface GenericIdentityFn {
<T>(arg: T): T
}
let c: GenericIdentityFn = identity
1、概述
说明
一个泛型类的形状和泛型接口是类似的
泛型类就是在类的名称后面加 <>
写入泛型参数列表
代码示例
代码语言:javascript代码运行次数:0运行复制此处报错,我们可以将
tscfig.json
里面的strictPropertyInitialization
属性值设置为fasle
以关闭该提示!
class Genericumber<umberType> {
// 属性
zeroValue: umberType
// 函数
add: (x: umberType, y: umberType) => umberType
}
2、代码演示
代码语言:javascript代码运行次数:0运行复制class Genericumber<umberType> {
zeroValue: umberType
add: (x: umberType, y: umberType) => umberType
}
// number
let myGeneric = new Genericumber<number>()
myGeneric.zeroValue = 0
myGeneric.add = function(x, y) {
return x + y
}
// string
let myGeneric1 = new Genericumber<string>()
myGeneric1.zeroValue = "0"
myGeneric1.add = function(x, y) {
return x + y
}
1、概述
说明
用户调用函数传入参数的时候就告诉其所传入参数必须具有的属性
代码示例
代码语言:javascript代码运行次数:0运行复制function loggingIdentity<Type extends Lengthwise>{}
2、代码演示
代码语言:javascript代码运行次数:0运行复制interface Lengthwise {
length: number
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type{
cole.log(arg.length)
return arg
}
// 测试
loggingIdentity("zibo") // 4
loggingIdentity([1, 2, ]) //
1、概述
说明
我们可以声明一个受另一个类型参数约束的类型参数
代码示例
代码语言:javascript代码运行次数:0运行复制<Key extends keyof Type>
2、代码演示
代码语言:javascript代码运行次数:0运行复制function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key]
}
let x = {
a: 1,
b: 2,
c: ,
d: 4
}
getProperty(x, 'a') // 此处传入的第二个参数 'a' 必须是 x 里面存在的 key
// getProperty(x, 'm') // 报错:类型“"m"”的参数不能赋给类型“"a" | "b" | "c" | "d"”的参数。
1、概述
说明
在 TypeScript 中使用泛型来创建工厂函数的时候
有必要通过其构造函数引用类的类型
代码示例
代码语言:javascript代码运行次数:0运行复制注意体会这个写法!是要传入一个类的,而不是类的实例!
function create<Type>(c: { new(): Type }): Type {
return new c()
}
2、代码演示
代码语言:javascript代码运行次数:0运行复制class Beekeeper {
hasMask: boolean = true
}
class Zookeeper {
nametag: string = "liubei"
}
class Animal {
numLegs: number = 4
}
class Bee extends Animal {
keeper: Beekeeper = new Beekeeper()
}
class Lion extends Animal {
keeper: Zookeeper = new Zookeeper()
}
function createInstance<A extends Animal>(c: new() => A): A {
return new c()
}
createInstance(Lion).
createInstance(Bee).keeper.hasMask
// 报错:
// 类型“typeof Beekeeper”的参数不能赋给类型“new () => Animal”的参数。
// 类型 "Beekeeper" 中缺少属性 "numLegs",但类型 "Animal" 中需要该属性。
// createInstance(Beekeeper)
1、概述
说明
keyof 运算符可以接收一个对象类型
它会产生它的 key 的字符串
或者与数字字面量的结合
或者可以说是一个联合类型
代码示例
代码语言:javascript代码运行次数:0运行复制type Point = { x: number, y: number}
type P = keyof Point
// P 是 "x" | "y"
ct p1: P = "x"
ct p2: P = "y"
2、代码演示
普通示例
代码语言:javascript代码运行次数:0运行复制type Point = { x: number, y: number}
type P = keyof Point
// P 是 "x" | "y"
ct p1: P = "x"
ct p2: P = "y"
ct p:P = "z" // 报错:不能将类型“"z"”分配给类型“keyof Point”。
索引签名
代码语言:javascript代码运行次数:0运行复制// number 类型
type Arrayish = {
[n: number]: unknown
}
type A = keyof Arrayish
// 此时为任意数字
ct a01: A = 0
ct a02: A = 2
ct a0: A = 19
// string | numer 类型
type Mapish = {
[k: string]: boolean
}
type M = keyof Mapish
ct m01: M = 0
ct m02: M = "hello"
ct m0: M = false // 报错:不能将类型“boolean”分配给类型“string | number”。
1、概述
说明
typeof 可以让我们在类型的上下文中使用它来引用一个变量或属性的类型
代码示例
代码语言:javascript代码运行次数:0运行复制let s = "hello"
// 使得 n 的类型为 s 的类型
let n: typeof s
// 打印的时候结果为:string
cole.log(typeof s)
n = "world"
2、代码演示
普通例子
代码语言:javascript代码运行次数:0运行复制cole.log(typeof "hello") // string
cole.log(typeof 100) // number
cole.log(typeof true) // boolean
cole.log(typeof { name: 'zibo', age: 25 }) // object
cole.log(typeof function go(){}) // function
ReturnType 例子
代码语言:javascript代码运行次数:0运行复制ReturnType:Ts 预定义的类型,返回当前函数返回值的类型!
type Predicate = (x: unknown) => boolean
// ReturnType:Ts 预定义的类型,返回当前函数返回值的类型
type K = ReturnType<Predicate>
let k: K = true
// 报错:不能将类型“number”分配给类型“boolean”。
let k01: K = 100
function f() {
return {
x: 10,
y:
}
}
cole.log(typeof f)
type P = ReturnType<typeof f>
// 报错:不能将类型“number”分配给类型“{ x: number; y: number; }”。ts(222)
ct p: P = 100
1、概述
说明
我们可以使用索引访问类型访问另一个类型上的特定属性
代码示例
代码语言:javascript代码运行次数:0运行复制type Person = {
age: number,
name: string,
alive: boolean
}
type Age = Person["age"]
2、代码演示
基本示例
代码语言:javascript代码运行次数:0运行复制type Person = {
age: number,
name: string,
alive: boolean
}
type Age = Person["age"]
let age: Age = 100
// 报错:不能将类型“string”分配给类型“number”。
// let age01: Age = "100"
联合类型
代码语言:javascript代码运行次数:0运行复制// Person 省略,见上面!
type Age = Person["age" | 'name']
let age: Age = 100
let age01: Age = "100"
// 报错:不能将类型“boolean”分配给类型“Age”。
let age02: Age = true
使用 keyof
代码语言:javascript代码运行次数:0运行复制// Person 省略,见上面!
// 此处 Age 的类型是 number | string | boolean
type Age = Person[keyof Person]
let age: Age = 100
let age01: Age = "100"
let age02: Age = true
使用联合文字类型
代码语言:javascript代码运行次数:0运行复制// Person 省略,见上面!
type myStr = "age" | "name"
// 此处 Age 的类型是 number | string
type Age = Person[myStr]
let age: Age = 100
let age01: Age = "100"
// 报错:不能将类型“boolean”分配给类型“Age”。
let age02: Age = true
从数组里面获得类型
代码语言:javascript代码运行次数:0运行复制ct MyArray = [
{ name: '大哥刘备', age: 5 },
{ name: '二哥关羽', age: },
{ name: '三哥张飞', age: 1 }
]
type Person = typeof MyArray[number]
let p: Person = {
name: '訾博',
age: 25
}
type P1 = Person['name']
let myame: P1 = "zibo"
另一种写法
代码语言:javascript代码运行次数:0运行复制ct key = 'name'
// 此写法报错:
// 类型“key”不能作为索引类型使用。ts(258)
// “key”表示值,但在此处用作类型。是否指“类型 key”?
type P2 = Person[key]
// 正确写法如下
type P = Person[typeof key]
let myame01: P = "name"
// 另一种写法
type key2 = 'name'
type P4 = Person[key2]
let myame02: P4 = "name"
1、概述
说明
所谓条件类型类似条件表达式(三目运算符)
代码示例
代码语言:javascript代码运行次数:0运行复制SomeType extends OtherType ? TrueType : FalseType
2、代码演示
基本使用
代码语言:javascript代码运行次数:0运行复制interface Animal {
live(): void
}
interface Dog extends Animal {
woof(): void
}
// type Example01 = number
type Example01 = Dog extends Animal ? number : string
优化函数重载
代码语言:javascript代码运行次数:0运行复制interface IdLabel {
id: number
}
interface ameLabel {
name: string
}
function createLabel(id: number): IdLabel
function createLabel(name: string): ameLabel
function createLabel(idOrame: number | string): IdLabel | ameLabel
function createLabel(idOrame: number | string): IdLabel | ameLabel {
throw ''
}
// 写起来很麻烦,我们可以使用条件类型解决
// 下面通过【条件类型】实现
type IdOrame<T extends number | string> = T extends number ? IdLabel : ameLabel
function createLabel01<T extends number | string>(idOrame: T): IdOrame<T> {
throw ''
}
// ameLabel
let a01 = createLabel01('hello')
// IdLabel
let a02 = createLabel01(111)
// IdLabel | ameLabel
let a0 = createLabel01(Math.random() > 0.5 ? 100 : "111")
1、概述
说明
通常条件类型中的检查会给我们提供一些新的信息
就像我们使用类型守卫缩小范围一样
可以给我们一个更具体的类型
条件类型的真正分支将通过我们的检查类型进一步约束泛型
代码示例
代码语言:javascript代码运行次数:0运行复制type MessageOf<T> = T extends { message: unknowm } ? T['message'] : never
2、代码演示
代码语言:javascript代码运行次数:0运行复制// 报错:类型“"message"”无法用于索引类型“T”
// type MessageOf<T> = T['message']
// 改造
type MessageOf<T extends { message: unknown }> = T['message']
interface Email {
message: string
}
type EmailMessageContents = MessageOf<Email>
let x01: EmailMessageContents = "hello"
// 再升级
type MessageOf01<T> = T extends { message: unknown } ? T['message'] : never
interface Dog {
name: string
}
type DogMessageContents = MessageOf01<Dog> // 不报错
let x02: DogMessageContents = "1111" // 报错:不能将类型“string”分配给类型“never”。
// 再来一个示例代码
type Flatten<T> = T extends any[] ? T[number] : T
type myStr = Flatten<string[]>
type myum = Flatten<number>
1、概述
说明
条件类型为我们提供了一种方法
来推断我们在真实分支中
使用 infer 关键字来进行对比的类型
代码示例
代码语言:javascript代码运行次数:0运行复制我们用 infer 关键字定义一个 Item 类型!
type Flatten<T> = T extends Array<infer Item> ? Item : T
2、代码演示
基本示例
代码语言:javascript代码运行次数:0运行复制type GetReturnType<T> = T extends (...args: never[]) => infer R ? R : never
// number
type um = GetReturnType<() => number>
let num: um = 100
// string
type Str = GetReturnType<(x: string) => string>
let str: Str = 'hello'
// boolean[]
type Bools = GetReturnType<(a: number, b: string, c: boolean) => Boolean[]>
let bools: Bools = [true, false]
// ever
type ever = GetReturnType<string>
let nev: ever = "never" // 报错:不能将类型“string”分配给类型“never”。
重载函数拓展
代码语言:javascript代码运行次数:0运行复制function stringOrum(x: string): number
function stringOrum(x: number): string
function stringOrum(x: string | number): string | number
function stringOrum(x: string | number): string | number {
return Math.random() > 0.5 ? "hello" : 100
}
type T1 = ReturnType<typeof stringOrum>
ct t1: T1 = "ss"
ct t2: T1 = 222
ct t: T1 = false // 报错:不能将类型“boolean”分配给类型“string | number”
1、概述
什么
当条件类型作用于一个通用类型的时候
我们给定它一个联合类型
它就变成了一个分布式的了
代码示例
代码语言:javascript代码运行次数:0运行复制此时,返回的类型是 string[] | number[]
type ToArray<T> = T extends any ? T[] : never
type StrOrumArr = ToArray<string | number>
2、代码演示
分布式
代码语言:javascript代码运行次数:0运行复制type ToArray<T> = T extends any ? T[] : never
type StrOrumArr = ToArray<string | number>
// 此时,返回的类型是 string[] | number[]
let son: StrOrumArr = ["111"]
let son01: StrOrumArr = [111]
let son02: StrOrumArr = [true] // 报错:不能将类型“boolean”分配给类型“string | number”
非分布式
代码语言:javascript代码运行次数:0运行复制type ToArrayonDist<T> = [T] extends [any] ? T[] : never
type StrArrOrumArr = ToArrayonDist<string | number>
// 此时,返回的类型是 string | number
let son0: StrArrOrumArr = ["11"]
let son04: StrArrOrumArr = [11]
let son05: StrArrOrumArr = [true] // 报错:不能将类型“boolean”分配给类型“string | number
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent 删除泛型函数索引typescriptstring #感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 14 条评论) |
本站网友 第一张大字报 | 23分钟前 发表 |
T) | |
本站网友 健康的减肥饮食 | 23分钟前 发表 |
number) | |
本站网友 后门程序 | 25分钟前 发表 |
是否指“类型 key”? type P2 = Person[key] // 正确写法如下 type P = Person[typeof key] let myame01 | |
本站网友 大岗租房 | 19分钟前 发表 |
umberType) => umberType } // number let myGeneric = new Genericumber<number>() myGeneric.zeroValue = 0 myGeneric.add = function(x | |
本站网友 法医鉴定轻伤 | 27分钟前 发表 |
number | |
本站网友 肾炎治疗 | 20分钟前 发表 |
T1 = false // 报错:不能将类型“boolean”分配给类型“string | number”十五 | |
本站网友 武汉都市女子医院 | 30分钟前 发表 |
number) | |
本站网友 阜城租房 | 10分钟前 发表 |
{ name | |
本站网友 计划经济时代 | 2分钟前 发表 |
概述说明条件类型为我们提供了一种方法来推断我们在真实分支中使用 infer 关键字来进行对比的类型代码示例 我们用 infer 关键字定义一个 Item 类型! 代码语言:javascript代码运行次数:0运行复制type Flatten<T> = T extends Array<infer Item> ? Item | |
本站网友 封闭式问题 | 20分钟前 发表 |
T } = identity泛型接口代码语言:javascript代码运行次数:0运行复制function identity<T>(arg | |
本站网友 整容医院哪个好 | 3分钟前 发表 |
never // number type um = GetReturnType<() => number> let num | |
本站网友 工行个人信用贷款 | 2分钟前 发表 |
number; y | |
本站网友 孕妇能不能吃螃蟹 | 12分钟前 发表 |
new() => A) |