[{"data":1,"prerenderedAt":408},["ShallowReactive",2],{"content:\u002F2022\u002Ftypescript\u002Fts-3":3,"surround:\u002F2022\u002Ftypescript\u002Fts-3":397},{"id":4,"title":5,"body":6,"categories":369,"date":372,"description":20,"draft":373,"extension":374,"image":375,"meta":376,"navigation":378,"path":379,"permalink":375,"published":375,"readingTime":380,"recommend":375,"references":375,"seo":385,"sitemap":386,"stem":393,"tags":394,"type":395,"updated":375,"__hash__":396},"content\u002Fposts\u002F2022\u002Ftypescript\u002Fts-3.md","TypeScript 中的类型（下）",{"type":7,"value":8,"toc":354},"minimark",[9,14,22,30,35,38,43,54,60,65,80,90,94,101,110,120,126,143,152,162,167,173,176,180,183,189,194,200,204,208,217,222,225,240,246,249,262,268,274,285,288,291,297,303,309,314,320,323,339,345,348],[10,11,13],"h2",{"id":12},"何时使用-enum","何时使用 enum",[15,16,17],"p",{},[18,19],"img",{"alt":20,"src":21},"","\u002Fimages\u002Ftypescript\u002Fts-3\u002Fts_3_01.png",[15,23,24,25,29],{},"实例一：用 ",[26,27,28],"code",{"code":28},"A.todo"," 将数字映射成一个有意义的语法",[15,31,32],{},[18,33],{"alt":20,"src":34},"\u002Fimages\u002Ftypescript\u002Fts-3\u002Fts_3_02.png",[15,36,37],{},"实例二：可以用于表示权限",[15,39,40],{},[18,41],{"alt":20,"src":42},"\u002Fimages\u002Ftypescript\u002Fts-3\u002Fts_3_03.png",[15,44,45,46,49,50,53],{},"以上代码中，",[26,47,48],{"code":48},"Manage = Read | Write | Delete"," 是 JS 中的二进制操作（二进制或运算符），",[26,51,52],{"code":52},"0b"," 在 JS 中表示二进制",[55,56,57],"blockquote",{},[15,58,59],{},"何时用 enum 会显得很呆？",[15,61,62],{},[18,63],{"alt":20,"src":64},"\u002Fimages\u002Ftypescript\u002Fts-3\u002Fts_3_04.png",[15,66,67,68,71,72,75,76,79],{},"如上所示，将 ",[26,69,70],{"code":70},"'apple'"," 映射为 ",[26,73,74],{"code":74},"Fruit.apple"," 完全是多此一举，还是别再用 ",[26,77,78],{"code":78},"enum"," 来映射字符串了吧ヾ(-_-;)",[55,81,82],{},[15,83,84,85,87,88],{},"只推荐用 ",[26,86,78],{"code":78}," 对数字做映射，除此之外都不推荐使用 ",[26,89,78],{"code":78},[10,91,93],{"id":92},"何时使用-type","何时使用 type",[15,95,96,97,100],{},"TS 中的 ",[26,98,99],{"code":99},"Type"," 叫作类型别名，Type Aliases，其实就是给其他类型取个名字，示例如下：",[102,103,108],"pre",{"className":104,"code":106,"language":107,"meta":20},[105],"language-ts","type Name = string;\ntype FalseLike = '' | 0 | false | null | undefined;\ntype Point = { x: number; y: number };\ntype Points = Point[];\ntype Line = [Point, Point];\ntype Circle = { center: Point; radius: number };\ntype Fn = (a: number, b: number) => number;\ntype FnWithProps = {\n  (a: number, b: number): number;\n  prop1: number;\n};\n","ts",[26,109,106],{"__ignoreMap":20},[15,111,112],{},[113,114,115,116,119],"strong",{},"如何体现出 ",[26,117,118],{"code":118},"type"," 只是一个别名？",[102,121,124],{"className":122,"code":123,"language":107,"meta":20},[105],"type X = { x: number }\ntype A = X\n",[26,125,123],{"__ignoreMap":20},[127,128,130],"folding",{"title":129},"以上 TS 代码中 A 的类型是？",[15,131,132,133,135,136,139,140],{},"由于 ",[26,134,118],{"code":118}," 只是一个别名，并不是声明了一个真正的类型，此处 ",[26,137,138],{"code":138},"A"," 的类型为 ",[26,141,142],{"code":142},"{ x: number }",[15,144,145],{},[113,146,147,148,151],{},"如何理解 ",[26,149,150],{"code":150},"type FalseLike = '' | 0 | false | null | undefined","？",[15,153,154,155,158,159,161],{},"上面的五个值其实都是类型，类型可以理解为集合，因此可以看作五个集合并在一起，每个集合中只包含一个值；另外，不支持 ",[26,156,157],{"code":157},"NaN"," 作为类型，因为 ",[26,160,157],{"code":157}," 表示的是一个值而不是类型",[15,163,164],{},[113,165,166],{},"带有属性的函数的声明方式",[102,168,171],{"className":169,"code":170,"language":107,"meta":20},[105],"type FnWithProps = {\n  (a: number, b: number): number;\n  props: string;\n};\n\nconst fn: FnWithProps = (x, y) => x * y;\n\nfn.props = 'hello';\n",[26,172,170],{"__ignoreMap":20},[15,174,175],{},"多用于 React 中",[10,177,179],{"id":178},"何时使用-interface","何时使用 interface",[15,181,182],{},"声明接口，用于描述对象的属性 declare the shapes of objects",[102,184,187],{"className":185,"code":186,"language":107,"meta":20},[105],"interface Data { [k: string]: string; }\ninterface Point { x: number; y: number; }\ninterface Points extends Array\u003CPoint> {}\ninterface Fn { (x: number, y: number): number; }\ninterface Date2 extends Date {}\n",[26,188,186],{"__ignoreMap":20},[15,190,191,193],{},[26,192,118],{"code":118}," 如何实现继承？",[102,195,198],{"className":196,"code":197,"language":107,"meta":20},[105],"interface X { age: number; }\n\ntype Al = Array\u003Cstring> & { name: string; } & X;\n\n\u002F\u002F A1几乎等价于A2\ninterface A2 extends Array\u003Cstring>, X { name: string; }\n",[26,199,197],{"__ignoreMap":20},[10,201,203],{"id":202},"type-和-interface-的区别","type 和 interface 的区别",[205,206,207],"h3",{"id":207},"区别一",[15,209,210,213,214,216],{},[26,211,212],{"code":212},"interface"," 只能描述对象，而 ",[26,215,118],{"code":118}," 能描述所有数据类型",[15,218,219],{},[18,220],{"alt":20,"src":221},"\u002Fimages\u002Ftypescript\u002Fts-3\u002Fts_3_05.png",[205,223,224],{"id":224},"区别二",[15,226,227,229,230,233,234,236,237],{},[26,228,118],{"code":118}," 并不会创建一个新的类型，只是创建了一个",[113,231,232],{},"类型别名","；而 ",[26,235,212],{"code":212}," 则是类型声明，会创建一个",[113,238,239],{},"新的类型",[102,241,244],{"className":242,"code":243,"language":107,"meta":20},[105],"type A = string;\ntype B = A; \u002F\u002F B 的类型是 string\n\ninterface D extends Date {}\ntype E = D; \u002F\u002F E 的类型是 D\n",[26,245,243],{"__ignoreMap":20},[205,247,248],{"id":248},"区别三",[15,250,251,253,254,233,256,258,259,261],{},[26,252,118],{"code":118}," 不可重新赋值，因此不能存在同名的 ",[26,255,118],{"code":118},[26,257,212],{"code":212}," 可以声明同名的类型，同名的 ",[26,260,212],{"code":212}," 会自动合并",[102,263,266],{"className":264,"code":265,"language":107,"meta":20},[105],"type A = string; \u002F\u002F 报错 Duplicate identifier 'A'\ntype A = number; \u002F\u002F 报错 Duplicate identifier 'A'\n\ninterface X { name: string; }\ninterface X { age: number; }\nconst x: X = { name: 'ClariS', age: 18 }; \u002F\u002F X 为 { name: string; age: number; }\n",[26,267,265],{"__ignoreMap":20},[15,269,270,271,273],{},"使用 ",[26,272,118],{"code":118}," 无法进行类型扩展，因此",[55,275,276],{},[15,277,278,279,281,282,284],{},"对外 API 尽量用 ",[26,280,212],{"code":212},"，方便用户进行类型扩展；对内 API 尽量用 ",[26,283,118],{"code":118},"，防止代码分散",[15,286,287],{},"例如，当你设计一个库或框架的公共 API 时，可以使用接口来定义输入和输出的数据结构，以提供明确的类型信息给用户，并允许用户按照自己的需求扩展接口。",[15,289,290],{},"而当你在代码内部定义一些仅在局部范围内使用的类型时，使用类型别名可以让代码更加集中和易于维护。它可以将类型定义与具体的实现逻辑分离开来，使代码更加模块化。",[15,292,293,294,296],{},"下面是一个扩展 ",[26,295,212],{"code":212}," 的实例：",[15,298,299,300],{},"扩展 ",[26,301,302],{"code":302},"axios",[102,304,307],{"className":305,"code":306,"language":107,"meta":20},[105],"import { AxiosRequestConfig } from 'axios';\ndeclare module 'axios' {\n  export interface AxiosRequestConfig {\n    _autoLoading?: boolean;\n    _mock?: string;\n  }\n}\n",[26,308,306],{"__ignoreMap":20},[15,310,299,311],{},[26,312,313],{"code":313},"string",[102,315,318],{"className":316,"code":317,"language":107,"meta":20},[105],"declare global {\n  interface String {\n    padZero(length: number): string;\n  }\n}\n",[26,319,317],{"__ignoreMap":20},[205,321,322],{"id":322},"区别四",[15,324,325,327,328,331,332,334,335,338],{},[26,326,212],{"code":212}," 使用 ",[26,329,330],{"code":330},"extends"," 来实现继承，而 ",[26,333,118],{"code":118}," 只能用 ",[26,336,337],{"code":337},"&"," 来模拟继承",[102,340,343],{"className":341,"code":342,"language":107,"meta":20},[105],"interface A {\n  a: string\n}\n\ninterface B extends A {\n  b: string\n}\n\ntype C = { c: string } & A\n",[26,344,342],{"__ignoreMap":20},[10,346,347],{"id":347},"void",[102,349,352],{"className":350,"code":351,"language":107,"meta":20},[105],"type Fn = () => void;\n\nconst fn: Fn = () => {\n  return 'xxx'; \u002F\u002F 不报错\n};\n\nconst x = fn();\n\nconsole.log(x.toString()); \u002F\u002F 报错：Property 'toString' does not exist on type 'void'.\n\nconsole.log((x as any).toString()); \u002F\u002F 不报错\n\nfunction fn1(a: number): void {\n  return 'xxx'; \u002F\u002F 报错：Type 'string' is not assignable to type 'void'.\n}\n\nconst fn2 = (a: number): void => {\n  return 'xxx'; \u002F\u002F 报错：Type 'string' is not assignable to type 'void'.\n};\n",[26,353,351],{"__ignoreMap":20},{"title":20,"searchDepth":355,"depth":355,"links":356},4,[357,359,360,361,368],{"id":12,"depth":358,"text":13},2,{"id":92,"depth":358,"text":93},{"id":178,"depth":358,"text":179},{"id":202,"depth":358,"text":203,"children":362},[363,365,366,367],{"id":207,"depth":364,"text":207},3,{"id":224,"depth":364,"text":224},{"id":248,"depth":364,"text":248},{"id":322,"depth":364,"text":322},{"id":347,"depth":358,"text":347},[370,371],"学习笔记","TypeScript","2022-12-29",false,"md",null,{"comments":373,"slots":377},{},true,"\u002F2022\u002Ftypescript\u002Fts-3",{"text":381,"minutes":382,"time":383,"words":384},"6 min read",5.03,301800,1006,{"title":5,"description":20},{"loc":379,"images":387},[388,389,390,391,392],{"loc":21},{"loc":34},{"loc":42},{"loc":64},{"loc":221},"posts\u002F2022\u002Ftypescript\u002Fts-3",[371,78],"tech","Rseaa9BVtZcp_Dj-J3KgtoUvPEDNO_R7_tX-eZpGcgY",[398,403],{"title":399,"path":400,"stem":401,"date":402,"type":395,"children":-1},"TypeScript 中的类型（上）","\u002F2022\u002Ftypescript\u002Fts-2","posts\u002F2022\u002Ftypescript\u002Fts-2","2022-12-28",{"title":404,"path":405,"stem":406,"date":407,"type":395,"children":-1},"TS 中的类型运算：联合类型","\u002F2023\u002Ftypescript\u002Fts-4","posts\u002F2023\u002Ftypescript\u002Fts-4","2023-01-12",1793699839562]