本文介绍了八、7. 类型兼容性是关键求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。
对技术面试,学习经验等有一些体会,在此分享。
在 ts 的开发中,类型兼容性无处不在。
可是大家在学习 ts 时,往往会忽略类型兼容性的重要性。
不理解类型兼容性,就容易在使用时出现很多无法理解的错误。实际使用时,往往需要对各种类型声明进行融合,而要合理的融合,那么类型兼容性就是关键。
一、子类型
非常简单的案例,
let a = 20 let b = 30 b = a // ✅ ok
在实践中,将一个变量,赋值给另外一个变量的场景非常多,因此这里就会涉及到,这两个变量的类型比较问题
如果 a 的类型,无法兼容 b 的类型,那么,这样的赋值就存在风险。
上面的例子中,a 与 b 的类型相同,因此可以相互兼容。
如果稍微调整一下,就会出现错误
let a = 20 let b = '500' b = a // ❌ error
错误提示:不能讲 number 类型分配给 string 类型
如果此时,我们将 b 的类型,进行一个扩展,让 b 的类型从 number 变成 number | string
,就会发现错误消失了
let a = 20 let b: number | string = '500' b = a // ✅ ok
因为我们可以将 number
类型分配给 number | string
类型。
但是反过来就不行,
let a = 20 let b: number | string = '500' a = b // ❌ error
原因就是因为 b 的类型可能是一个 string 类型,当其为 string 类型时,就无法分配给 a 的 number 类型。
因此,在这种情况下。被赋值的类型范围,要大于等于赋值的类型范围。
此时我们基于这个例子,来探讨一下子类型的概念。
从语义上,我们可以很容易知道,Person 类,是父类,而 Student 类,是子类。因为 Person 类,概念更宽泛。而 Student 类,概念更具体。
因此,更具体的我们称之为子类。也可以称之为我们这里的子类型。
那么有如下两个类型
type A = number type B = number | string
他们谁是子类型,谁是父类型呢?
概念更宽泛的为父类型,也就是 B
概念更具体的为子类型,也就是 A
从概念范围上来说,我们用 A <= B
来表示 A 是 B 的子类型。
在设计模式的章节中,我们学习过里氏替换原则,也可以扩展到我们的类型兼容性里,任何使用父类型的地方,都能够用子类型替换。
因此,我们再来看一下这个例子,b = a
,其实就是子类型,替换父类型。也就是说,子类型能够赋值给父类型。反之则不行。
let a = 20 let b: number | string = '500' // 子类型、替换 父类型 b = a
再来看一个对象的例子。
首先定义一个数据类型如下
interface User { id: string, name: string, phone: string, pwd: string }
声明一个变量,该变量的类型为 User,具体赋值的字段对象,要比 User 中的多一个
interface User { id: string, name: string, phone: string, pwd: string } let defUser1 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', pwd: '123123', age: 20 } let defUser2 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', } const user: User = defUser1 // ✅ ok const user2: User = defUser2 // ❌ error
在 ts 的开发中,类型兼容性无处不在。
可是大家在学习 ts 时,往往会忽略类型兼容性的重要性。
不理解类型兼容性,就容易在使用时出现很多无法理解的错误。实际使用时,往往需要对各种类型声明进行融合,而要合理的融合,那么类型兼容性就是关键。
一、子类型
非常简单的案例,
let a = 20 let b = 30 b = a // ✅ ok
在实践中,将一个变量,赋值给另外一个变量的场景非常多,因此这里就会涉及到,这两个变量的类型比较问题
如果 a 的类型,无法兼容 b 的类型,那么,这样的赋值就存在风险。
上面的例子中,a 与 b 的类型相同,因此可以相互兼容。
如果稍微调整一下,就会出现错误
let a = 20 let b = '500' b = a // ❌ error
错误提示:不能讲 number 类型分配给 string 类型
如果此时,我们将 b 的类型,进行一个扩展,让 b 的类型从 number 变成 number | string
,就会发现错误消失了
let a = 20 let b: number | string = '500' b = a // ✅ ok
因为我们可以将 number
类型分配给 number | string
类型。
但是反过来就不行,
let a = 20 let b: number | string = '500' a = b // ❌ error
原因就是因为 b 的类型可能是一个 string 类型,当其为 string 类型时,就无法分配给 a 的 number 类型。
因此,在这种情况下。被赋值的类型范围,要大于等于赋值的类型范围。
此时我们基于这个例子,来探讨一下子类型的概念。
从语义上,我们可以很容易知道,Person 类,是父类,而 Student 类,是子类。因为 Person 类,概念更宽泛。而 Student 类,概念更具体。
因此,更具体的我们称之为子类。也可以称之为我们这里的子类型。
那么有如下两个类型
type A = number type B = number | string
他们谁是子类型,谁是父类型呢?
概念更宽泛的为父类型,也就是 B
概念更具体的为子类型,也就是 A
从概念范围上来说,我们用 A <= B
来表示 A 是 B 的子类型。
在设计模式的章节中,我们学习过里氏替换原则,也可以扩展到我们的类型兼容性里,任何使用父类型的地方,都能够用子类型替换。
因此,我们再来看一下这个例子,b = a
,其实就是子类型,替换父类型。也就是说,子类型能够赋值给父类型。反之则不行。
let a = 20 let b: number | string = '500' // 子类型、替换 父类型 b = a
再来看一个对象的例子。
首先定义一个数据类型如下
interface User { id: string, name: string, phone: string, pwd: string }
声明一个变量,该变量的类型为 User,具体赋值的字段对象,要比 User 中的多一个
interface User { id: string, name: string, phone: string, pwd: string } let defUser1 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', pwd: '123123', age: 20 } let defUser2 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', } const user: User = defUser1 // ✅ ok const user2: User = defUser2 // ❌ error
在 ts 的开发中,类型兼容性无处不在。
可是大家在学习 ts 时,往往会忽略类型兼容性的重要性。
不理解类型兼容性,就容易在使用时出现很多无法理解的错误。实际使用时,往往需要对各种类型声明进行融合,而要合理的融合,那么类型兼容性就是关键。
一、子类型
非常简单的案例,
let a = 20 let b = 30 b = a // ✅ ok
在实践中,将一个变量,赋值给另外一个变量的场景非常多,因此这里就会涉及到,这两个变量的类型比较问题
如果 a 的类型,无法兼容 b 的类型,那么,这样的赋值就存在风险。
上面的例子中,a 与 b 的类型相同,因此可以相互兼容。
如果稍微调整一下,就会出现错误
let a = 20 let b = '500' b = a // ❌ error
错误提示:不能讲 number 类型分配给 string 类型
如果此时,我们将 b 的类型,进行一个扩展,让 b 的类型从 number 变成 number | string
,就会发现错误消失了
let a = 20 let b: number | string = '500' b = a // ✅ ok
因为我们可以将 number
类型分配给 number | string
类型。
但是反过来就不行,
let a = 20 let b: number | string = '500' a = b // ❌ error
原因就是因为 b 的类型可能是一个 string 类型,当其为 string 类型时,就无法分配给 a 的 number 类型。
因此,在这种情况下。被赋值的类型范围,要大于等于赋值的类型范围。
此时我们基于这个例子,来探讨一下子类型的概念。
从语义上,我们可以很容易知道,Person 类,是父类,而 Student 类,是子类。因为 Person 类,概念更宽泛。而 Student 类,概念更具体。
因此,更具体的我们称之为子类。也可以称之为我们这里的子类型。
那么有如下两个类型
type A = number type B = number | string
他们谁是子类型,谁是父类型呢?
概念更宽泛的为父类型,也就是 B
概念更具体的为子类型,也就是 A
从概念范围上来说,我们用 A <= B
来表示 A 是 B 的子类型。
在设计模式的章节中,我们学习过里氏替换原则,也可以扩展到我们的类型兼容性里,任何使用父类型的地方,都能够用子类型替换。
因此,我们再来看一下这个例子,b = a
,其实就是子类型,替换父类型。也就是说,子类型能够赋值给父类型。反之则不行。
let a = 20 let b: number | string = '500' // 子类型、替换 父类型 b = a
再来看一个对象的例子。
首先定义一个数据类型如下
interface User { id: string, name: string, phone: string, pwd: string }
声明一个变量,该变量的类型为 User,具体赋值的字段对象,要比 User 中的多一个
interface User { id: string, name: string, phone: string, pwd: string } let defUser1 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', pwd: '123123', age: 20 } let defUser2 = { id: 'xxx1234sd', name: '张三', phone: '12312312313', } const user: User = defUser1 // ✅ ok const user2: User = defUser2 // ❌ error
部分转自互联网,侵权删除联系
最新评论