TypeScript学习(十)——缩小类型限制范围

编程入门 行业动态 更新时间:2024-10-09 08:27:17

TypeScript学习(十)——缩小<a href=https://www.elefans.com/category/jswz/34/1771355.html style=类型限制范围"/>

TypeScript学习(十)——缩小类型限制范围

文章目录

    • typeof缩小类型限制范围
      • typeof的作用
      • typeof返回的值
      • typeof能帮我们检测js疑难杂症之typeof null === 'object'
    • 条件判断 / && / || / ! 来缩小类型限制范围
      • 解决上面的报错
      • js的判断不只是判断布尔值
      • ts的检测是沿着作用域的开展的
    • 相等判断来缩小类型限制范围
      • === / !== 严格相等性判断
      • == / != 宽松相等性判断
    • in判断来缩小类型限制范围
      • in只是在编译时判断是否可能是某类型,而不会认为这个属性一定会存在
    • instanceof来缩小类型限制范围
      • instanceof的作用
    • =赋值来缩小ts的限制范围
    • 程序控制流缩小限制范围
    • 约束唯一缩小限制范围
      • 合并书写
      • 拆分成多个类型减少判断
    • never
      • 缩小到没有类型限制
      • never传递类型

typeof缩小类型限制范围

typeof的作用

function padLeft(padding: number | string, input: string) {// 因为repeat重复字符串api接收一个number类型的参数所以需要加typeof限制它的类型只能是numberif (typeof padding === "number") {return " ".repeat(padding) + input;}return padding + input
}
console.log(padLeft(5,"你好"));
console.log(padLeft("     ","你好"));

typeof返回的值

typeof能帮我们检测js疑难杂症之typeof null === ‘object’

function test(msg:object | string | null){/* js的typeof判断null时,返回的值也为‘object’,因此下面的判断依然会有可能导致程序报错而ts则可以在程序编译时帮我们检测出来 */if(typeof msg === 'object'){Object.keys(msg)}
}

条件判断 / && / || / ! 来缩小类型限制范围

解决上面的报错

function test(msg:object | string | null){/* js的typeof判断null时,返回的值也为‘object’,因此下面的判断依然会有可能导致程序报错而ts则可以在程序编译时帮我们检测出来 */if(typeof msg === 'object' && msg !== null){Object.keys(msg)}
}

js的判断不只是判断布尔值

js判断时,走否逻辑时的值不一定为布尔值false,以下值也可以是false

ts的检测是沿着作用域的开展的

function printAll(strs: string | string[] | null) {// 传入一个“”空字符串,ts判断为false不会走if里面的逻辑,从而会跳过下级作用域的检测if (strs) {if (typeof strs === "object") {for (const s of strs) {console.log(s);}} else if (typeof strs === "string") {console.log(strs);}}else {console.log('else');}
}
printAll("");

相等判断来缩小类型限制范围

=== / !== 严格相等性判断

ts校验在发现他们两个值相等时,会将他们的类型置为相同,当他们不同时,且至少有一个类型相同,那么他们的类型限制都会变成他们的之前类型限制的并集

function example(x: string | number, y: string | boolean) {if (x === y) {// 如果他们两个相等,取他们类型的交集x.toUpperCase(); y.toLowerCase();} else {// 如果他们两个不想等,取他们类型的并集,且他们至少有一个类型相同console.log(x);console.log(y);}
}
example(1,"1");
function example(x: string | number, y: symbol | boolean) {// 如果他们类型没有相等的部分,那么他们必是不相等的,那么判断就会变得没有意义if (x === y) {} else {}
}
example(1,false);

== / != 宽松相等性判断

interface Container {value: number | null | undefined;
}function multiplyValue(container: Container, factor: number) {// 宽松型的不等判断时,会将null和undefined作为同等情况if (container.value != null) {console.log(container.value);                 container.value *= factor;}
}

in判断来缩小类型限制范围

in只是在编译时判断是否可能是某类型,而不会认为这个属性一定会存在

type Fish = { swim: () => void };
type Bird = { fly: () => void };
type Human = { swim?: () => void; fly?: () => void };function move(animal: Fish | Bird | Human) {if ("swim" in animal) {// in 判断符会去类型中找符合情况的Fish和Human类型作为这个if作用域中animal的类型。if(animal.swim){// 但是只是判断这个属性有没有可能会出现在这个类型中,而不会认为一定会存在这个属性。animal.swim();}} else {}
}
move({swim:function(){console.log("Hello World")}})

instanceof来缩小类型限制范围

instanceof的作用

x instanceof Foo检查x的原型链是否包含Foo.prototype。

function logValue(x: Date | string) {if (x instanceof Date) {// x.__proto__ === Date.prototype// 那么此时在这个if中的x的类型限制则为Dateconsole.log(x.toUTCString());} else {// 反之x的类型为stringconsole.log(x.toUpperCase());           }
}
logValue(new Date());
logValue("hello world");

=赋值来缩小ts的限制范围

ts在赋值的时候,会去看赋值的右边的值是什么类型从而将值的类型作为右边变量的类型限制(多个值即为联合类型)

/* 在let const var 等申明符声明变量赋值时,ts会去查看赋值右边的值
为什么类型,从而将这个类型赋值给右边的变量在此时为number | string */
let x = Math.random() < 0.5 ? 10 : "hello world!";
// 那么将number类型重新赋值给x不会报错
x = 1;
// 同理赋值string类型也不会报错
x = "Hello World";
console.log(x);
// 但是将number | string 的其它类型如boolean赋值给x则会抛出提示         
x = true;
console.log(x);

程序控制流缩小限制范围

一个变量的类型在程序运行的过程中,后根据程序运行流在类型的子集中根据使用情况不断变换类型限制

function example() {let x: string | number | boolean;x = Math.random() < 0.5;console.log(x); // booleanif (Math.random() < 0.5) {x = "hello";console.log(x);// string} else {x = 100;console.log(x);// number}return x;
}

约束唯一缩小限制范围

合并书写

interface Shape {kind: "circle" | "square";radius?: number;sideLength?: number;
}function getArea(shape: Shape) {if (shape.kind === "circle") {// 判断是什么类型限制(只能是circle/square),radius不能为空return Math.PI * shape.radius! ** 2;}else {return shape.sideLength! ** 2}
}

拆分成多个类型减少判断

interface Circle {kind: "circle";radius: number;
}interface Square {kind: "square";sideLength: number;
}type Shape = Circle | Square;function getArea(shape: Shape) {switch (shape.kind) {case "circle":return Math.PI * shape.radius ** 2;case "square":return shape.sideLength ** 2;}
}

never

缩小到没有类型限制

type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {if ("swim" in animal) {if(animal.swim){animal.swim();}}else if("fly" in animal){if(animal.fly){animal.fly();} }else {console.log(animal)}
}

never传递类型

never 类型可分配给每种类型。但是,没有任何类型可以分配给 never(除了 never 本身)。

type Shape = Circle | Square;function getArea(shape: Shape) {switch (shape.kind) {case "circle":return Math.PI * shape.radius ** 2;case "square":return shape.sideLength ** 2;default:// 如果前面两种情况都不满足,此时的shape类型为never,可以将never分配给never类型限制的变量const _exhaustiveCheck: never = shape;return _exhaustiveCheck;}
}

but

interface Circle {kind: "circle";radius: number;
}interface Square {kind: "square";sideLength: number;
}interface Triangle {kind: "triangle";sideLength: number;
}type Shape = Circle | Square | Triangle;function getArea(shape: Shape) {switch (shape.kind) {case "circle":return Math.PI * shape.radius ** 2;case "square":return shape.sideLength ** 2;default:// 走完前面两个判断此时的shape类型限制为Triangle,除了never能分配给never之外,其它了类型不能分配给neverconst _exhaustiveCheck: never = shape;return _exhaustiveCheck;}
}

更多推荐

TypeScript学习(十)——缩小类型限制范围

本文发布于:2024-02-28 01:43:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1767420.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   TypeScript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!