亲爱的朋友们,由于公众号平台修改了推送规则,如果您不想错过我们的文章typescript 类型转化,看完后记得点击“在看”,这样每次有新文章推送时,都会出现在您的订阅中尽快列出来~
类型推断
在 TypeScript 中,在某些没有明确强调类型的地方,类型推断将有助于提供类型
例子:
let x = [0, 1, null] // number
let x = Math.random() < 0.5 ? 100 : "helloword" // number|string
let x: Animal[] = [new Rhino(), new Elephant(), new Snake()]; // Rhino | Elephant | Snake
如果没有找到最佳泛型类型,则类型推断的结果是联合字段类型
联合类型和类型防护
例子:
// 联合类型
type Types = number | string
function typeFn(type: Types, input: string): string {
// 如果这样写就需要判断type的类型
}
直接参数类型推断
let x:number|string = 1
x="tiedan"
如果不判断就会报错
function typeFn(type: number | string, input: string) {
// 报错 运算符+号不能应用于 string
return new Array(type + 1).join("") + input
}
所以必须判断
function typeFn(type: number | string, input: string) {
// 类型守卫
if (typeof type === 'number') {
return new Array(type + 1).join(" ") + input
}
return type + input
}
类型缩小就是根据判断类型重新定义更具体的类型
那么问题来了,为什么要学这些东西呢? js不好吗?
个人想法:
typeof 的类型保护:
"string"
"number"
"bigint" // ES10新增
"boolean"
"symbol" // ES6新增
"undefined"
"object"
"function"
注意:typeof null 等于 object
所以:
function strOrName(str: string | string[] | null) {
if (typeof str === 'object') {
for (const s of str) {
// 报错 因为str有可能是null
console.log(s)
}
} else if (typeof str === 'string') {
console.log(str)
} else {
//......
}
}
真相缩小
js的真值表很复杂,以下为假,其余为真。
0
NAN
""
0n // 0的bigint版本
null
undefined
借助真值可以缩小避免空错误的范围
// 利用真值判断
if (str && typeof strs === 'object') {
for (const s of strs) {
console.log(s)
}
}
或者
function valOrName(values: number[] | undefined, filter: number): number[] | undefined {
if (!values) {
return values
} else {
return values.filter(x => x > filter)
}
}
总结:真相缩小帮助我们更好地处理 null/undefined/0 等值
平等缩小
等式缩小是借助 ===、!==、==、and、!= 等运算符进行缩小
示例1:
function strOrNum(x: string | number, y: string | boolean) {
if (x === y) {
// string
} else {
// string|number
}
}
示例2:
function strOrName(str: string | string[] | null) {
if (str !== null) {
if (typeof str === 'object') {
for (const s of str) {
console.log(s) // []
}
} else if (typeof str === 'string') {
console.log(str) // string
} else {
// .....
}
}
}
例3:
interface Types {
value: number | null | undefined
}
function valOrType(type: Types, val: number) {
// null和undefined 都是false 只能是number
if (type.value != null) {
type.value *= val
}
}
操作符缩小
in是检测对象中是否有属性typescript 类型转化,现在充当“类型守卫”的角色。
例子:
interface A { a: number };
interface B { b: string };
function foo(x: A | B) {
if ("a" in x) {
return x.a;
}
return x.b;
}
缩小实例
instanceof 表达式的一侧必须是 any 类型,或者是可分配给 Function 套接字类型的类型。
例子:
function dateInval(x: Date | string) {
if (x instanceof Date) {
// Date
} else {
// string
}
}
缩小的本质
缩小的本质是重新定义类型
例子:
function example() {
let x: string | number | boolean
x = Math.random() < 0.5
if (Math.random() < 0.5) {
x = 'hello' // string
} else {
x = 100 // number
}
return x; // string|number
}
缩小联合类型
示例1:
interface Shape {
kind: "cirle" | "square",
redius?: number
sideLength?: number
}
// 报错
function getArea(shape: Shape) {
return Math.PI * shape.redius ** 2
}
// 窄化还是报错
function getArea(shape: Shape) {
if (shape.kind === 'cirle') {
return Math.PI * shape.redius ** 2
}
}
// 利用非空断言阔以
function getArea(shape: Shape) {
if (shape.kind === 'cirle') {
return Math.PI * shape.redius! ** 2
}
}
示例2:
interface Circle {
kind: "cirle";
redius: number;
}
interface Square {
kind: "square";
redius: number;
}
type Shape = Circle | Square
function getArea(shape: Shape) {
if (shape.kind === 'cirle') { // 窄化
return Math.PI * shape.redius ** 2
}
}
// 或者
function getArea(shape: Shape) {
switch (shape.kind) {
case "cirle":
return Math.PI * shape.redius ** 2
case "square":
return shape.sideLength ** 2
default:
const _example: never = shape
return _example
}
}
坚持每天晚上进步一点点,欢迎大家原谅,一起努力,共同进步。