[{"data":1,"prerenderedAt":482},["ShallowReactive",2],{"content:\u002F2022\u002Ftypescript\u002Fts-2":3,"surround:\u002F2022\u002Ftypescript\u002Fts-2":471},{"id":4,"title":5,"body":6,"categories":438,"date":441,"description":20,"draft":442,"extension":443,"image":444,"meta":445,"navigation":447,"path":448,"permalink":444,"published":444,"readingTime":449,"recommend":444,"references":444,"seo":454,"sitemap":455,"stem":467,"tags":468,"type":469,"updated":444,"__hash__":470},"content\u002Fposts\u002F2022\u002Ftypescript\u002Fts-2.md","TypeScript 中的类型（上）",{"type":7,"value":8,"toc":419},"minimark",[9,14,22,26,31,54,59,64,69,83,93,98,102,107,130,134,155,159,164,183,187,192,195,204,207,224,229,232,238,255,258,267,273,280,286,289,295,301,305,320,330,343,351,360,366,370,373,387,390],[10,11,13],"h2",{"id":12},"jsts-中有哪些数据类型","JS\u002FTS 中有哪些数据类型",[15,16,17],"p",{},[18,19],"img",{"alt":20,"src":21},"","\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_01.png",[10,23,25],{"id":24},"用集合来理解-ts-数据类型","用集合来理解 TS 数据类型",[15,27,28],{},[18,29],{"alt":20,"src":30},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_06.png",[15,32,33,37,38,41,42,45,46,49,50,53],{},[34,35,36],"code",{"code":36},"number"," 可看做 1、1.1、2、2.3 等所有数字值组成的集合\n",[34,39,40],{"code":40},"string"," 可看做 a、b、ab、c、abc 等所有字符串值组成的集合\n",[34,43,44],{"code":44},"boolean"," 可看做 ",[34,47,48],{"code":48},"true"," 和 ",[34,51,52],{"code":52},"false"," 这两个值组成的集合",[15,55,56],{},[18,57],{"alt":20,"src":58},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_07.png",[15,60,61],{},[18,62],{"alt":20,"src":63},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_08.png",[15,65,66],{},[18,67],{"alt":20,"src":68},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_09.png",[15,70,71,72,75,76,75,79,82],{},"JS 中的 ",[34,73,74],{"code":74},"Number","、",[34,77,78],{"code":78},"String",[34,80,81],{"code":81},"Boolean"," 只用于包装对象，一般不会用到它们；同样地在 TS 中也不会用到它们。",[15,84,85,86,89,90,92],{},"TS 中一般不会用 ",[34,87,88],{"code":88},"Object"," 来描述对象的类型，因为 ",[34,91,88],{"code":88}," 所表示的类型范围太大了",[15,94,95],{},[18,96],{"alt":20,"src":97},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_10.png",[10,99,101],{"id":100},"如何用-ts-来描述对象","如何用 TS 来描述对象",[15,103,104],{},[18,105],{"alt":20,"src":106},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_05.png",[108,109,110,122],"ol",{},[111,112,113,114,117,118,121],"li",{},"用 ",[34,115,116],{"code":116},"class","\u002F",[34,119,120],{"code":120},"constructor"," 描述",[111,123,113,124,117,127,121],{},[34,125,126],{"code":126},"type",[34,128,129],{"code":129},"interface",[131,132,133],"h3",{"id":133},"描述普通对象",[15,135,136,137,117,140,142,143,147,148,151,152],{},"由于 ",[34,138,139],{"code":139},"object",[34,141,88],{"code":88}," 太不精确，所以一般使用",[144,145,146],"strong",{},"索引签名","或",[144,149,150],{},"Record 泛型","来描述",[144,153,154],{},"普通对象",[156,157,158],"h4",{"id":158},"使用索引签名",[15,160,161],{},[18,162],{"alt":20,"src":163},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_02.png",[165,166,168],"folding",{"title":167},"思考题：key 的类型可以不是 string 吗？",[15,169,170,171,174,175,75,177,75,179,182],{},"经测试，",[34,172,173],{"code":173},"k"," 的类型只能为 ",[34,176,36],{"code":36},[34,178,40],{"code":40},[34,180,181],{"code":181},"symbol"," 这三种",[156,184,186],{"id":185},"使用-record","使用 Record",[15,188,189],{},[18,190],{"alt":20,"src":191},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_03.png",[156,193,194],{"id":194},"使用具体的字段",[196,197,202],"pre",{"className":198,"code":200,"language":201,"meta":20},[199],"language-ts","type A = {\n  name: string;\n  age: number;\n};\n","ts",[34,203,200],{"__ignoreMap":20},[131,205,206],{"id":206},"描述数组对象",[15,208,136,209,212,213,216,217,216,220,223],{},[34,210,211],{"code":211},"Array"," 太不精确，所以一般用 ",[34,214,215],{"code":215},"Array\u003C?>"," 或 ",[34,218,219],{"code":219},"string[]",[34,221,222],{"code":222},"[string, number]"," 来描述数组",[15,225,226],{},[18,227],{"alt":20,"src":228},"\u002Fimages\u002Ftypescript\u002Fts-2\u002Fts_2_04.png",[15,230,231],{},"思考题",[196,233,236],{"className":234,"code":235,"language":201,"meta":20},[199],"type A = [1, 2, 3]\nconst a: A = ??????\n",[34,237,235],{"__ignoreMap":20},[165,239,241],{"title":240},"以上 TS 代码中 a 的值是？",[15,242,243,244,247,248,251,252],{},"当于只有一个元素的",[144,245,246],{},"集合","，因此 ",[34,249,250],{"code":250},"a"," 的值只能是 ",[34,253,254],{"code":254},"[1, 2, 3]",[131,256,257],{"id":257},"描述函数对象",[15,259,136,260,212,263,266],{},[34,261,262],{"code":262},"Function",[34,264,265],{"code":265},"() => ?"," 来描述函数",[196,268,271],{"className":269,"code":270,"language":201,"meta":20},[199],"type FnA = (a: number, b: number) => number;\n\ntype FnReturnVoid = (s: string) => void;\n\ntype FnReturnUndefined = (s: string) => undefined;\n\nconst v: FnReturnVoid = (s: string) => {\n  console.log(s);\n};\n\nconst u: FnReturnUndefined = (s: string) => {\n  console.log(s);\n  return undefined;\n};\n",[34,272,270],{"__ignoreMap":20},[15,274,275,276,279],{},"带有 ",[34,277,278],{"code":278},"this"," 的函数声明",[196,281,284],{"className":282,"code":283,"language":201,"meta":20},[199],"type Person = {name: string, age: number, sayHi: FnWithThis}\ntype FnWithThis = (this: Person, name: string) => void\n\nconst sayHi: FnWithThis = function(name) { \u002F\u002F 此处不能使用箭头函数，因为箭头函数内不存在 this\n  console.log(\"hi\", this.name)\n}\n\nconst x: Person = {name: \"vivy\", age: 18, sayHi}\n\n\u002F\u002F 如果函数声明中有 this，那么调用函数时必须显示地传递这个 this\nx.sayHi(\"Citrus\")\nsayHi.call(x, \"Citrus\")\n",[34,285,283],{"__ignoreMap":20},[131,287,288],{"id":288},"描述其他对象",[15,290,291,292,294],{},"直接用 ",[34,293,116],{"code":116},"（构造函数） 描述即可",[196,296,299],{"className":297,"code":298,"language":201,"meta":20},[199],"const d: Date = new Date();\n\nconst r: RegExp = \u002Fab+c\u002F;\n\nconst m: Map\u003Cstring, number> = new Map();\nm.set('xxx', 1);\n\nconst wm: WeakMap\u003C{ name: string }, number> = new WeakMap();\n\nconst s: Set\u003C{ name: string }> = new Set();\ns.add({ name: 'ClariS' });\n\nconst ws: WeakSet\u003Cstring[]> = new WeakSet();\n",[34,300,298],{"__ignoreMap":20},[10,302,304],{"id":303},"anyunknownnever-是什么","any、unknown、never 是什么",[15,306,307,308,311,312,315,316,319],{},"从集合的角度理解：",[34,309,310],{"code":310},"any"," 是全集，",[34,313,314],{"code":314},"never"," 是空集，",[34,317,318],{"code":318},"unknown"," 是未知集",[15,321,322,323,326,327,329],{},"TS 的",[144,324,325],{},"绝大部分","规则对 ",[34,328,310],{"code":310}," 类型不生效（TS 不报错）",[15,331,332,333,335,336,339,340,342],{},"可对 ",[34,334,318],{"code":318}," 进行断言，适用于值是从外部获取的，没办法提前知道类型的情况；比如当使用 ",[34,337,338],{"code":338},"ajax"," 获取数据时，后台返回的数据格式不确定，此时可将接口响应的数据类型可定义为 ",[34,341,318],{"code":318},"，然后再对其进行断言",[196,344,349],{"className":345,"code":347,"language":348,"meta":20},[346],"language-TS","const a: unknown = await ajax.get('\u002Fapi\u002Fusers')\nconst b = a as number\n","TS",[34,350,347],{"__ignoreMap":20},[15,352,353,355,356,359],{},[34,354,314],{"code":314}," 一般不会用来声明类型，而是用来进行",[144,357,358],{},"类型推断","的",[196,361,364],{"className":362,"code":363,"language":201,"meta":20},[199],"type A = string | number | boolean;\n\nconst a: A = 'hello' as any;\n\nif (typeof a === 'string') {\n  a.split('');\n} else if (typeof a === 'number') {\n  a.toFixed(2);\n} else if (typeof a === 'boolean') {\n  a.valueOf();\n} else {\n  a.toString(); \u002F\u002F 报错：Property 'toString' does not exist on type 'never'\n}\n",[34,365,363],{"__ignoreMap":20},[10,367,369],{"id":368},"js-类型与-ts-类型的区别","JS 类型与 TS 类型的区别",[15,371,372],{},"我是这么理解的：",[15,374,375,376,75,378,75,380,382,383,386],{},"JS 这门语言其实并没有提供类型相关的关键字（如小写的 ",[34,377,36],{"code":36},[34,379,40],{"code":40},[34,381,44],{"code":44},"），只是提供了",[34,384,385],{"code":385},"typeof","让我们获取变量的类型，所以我认为 JS 对类型非常不重视。",[15,388,389],{},"而 TS 则将 JS 中的类型提升到很高的位置，高到如果你把类型写错了代码就不能通过编译。因此这两门语言中的类型其实没有可比性，只是看起来有重叠部分而已。如果一定要比较，我会这么说：",[108,391,392,404],{},[111,393,394,397,398,400,401,403],{},[144,395,396],{},"粒度不同","：在 JS 中的类型 ",[34,399,36],{"code":36}," 不可再细分，而 TS 中的 ",[34,402,36],{"code":36}," 可以看做 1、1.1、2、2.3 等无数个小类型的联合",[111,405,406,409,410,412,413,415,416,418],{},[144,407,408],{},"可变性不同","：JS 中的变量类型是可变的，一个 ",[34,411,36],{"code":36}," 随时可以变成一个 ",[34,414,40],{"code":40},"；TS 中除了 ",[34,417,310],{"code":310},"，其他类型要么是不可变的，要么就算可变也是有限制的",{"title":20,"searchDepth":420,"depth":420,"links":421},4,[422,424,425,436,437],{"id":12,"depth":423,"text":13},2,{"id":24,"depth":423,"text":25},{"id":100,"depth":423,"text":101,"children":426},[427,433,434,435],{"id":133,"depth":428,"text":133,"children":429},3,[430,431,432],{"id":158,"depth":420,"text":158},{"id":185,"depth":420,"text":186},{"id":194,"depth":420,"text":194},{"id":206,"depth":428,"text":206},{"id":257,"depth":428,"text":257},{"id":288,"depth":428,"text":288},{"id":303,"depth":423,"text":304},{"id":368,"depth":423,"text":369},[439,440],"学习笔记","TypeScript","2022-12-28",false,"md",null,{"comments":442,"slots":446},{},true,"\u002F2022\u002Ftypescript\u002Fts-2",{"text":450,"minutes":451,"time":452,"words":453},"5 min read",4.66,279600,932,{"title":5,"description":20},{"loc":448,"images":456},[457,458,459,460,461,462,463,464,465,466],{"loc":21},{"loc":30},{"loc":58},{"loc":63},{"loc":68},{"loc":97},{"loc":106},{"loc":163},{"loc":191},{"loc":228},"posts\u002F2022\u002Ftypescript\u002Fts-2",[440],"tech","u5pC_BSbuNW6xBHsgCDK90XzTfuE6Gjariunjc-I5oA",[472,477],{"title":473,"path":474,"stem":475,"date":476,"type":469,"children":-1},"TypeScript 的运行与调试","\u002F2022\u002Ftypescript\u002Fts-1","posts\u002F2022\u002Ftypescript\u002Fts-1","2022-09-07",{"title":478,"path":479,"stem":480,"date":481,"type":469,"children":-1},"TypeScript 中的类型（下）","\u002F2022\u002Ftypescript\u002Fts-3","posts\u002F2022\u002Ftypescript\u002Fts-3","2022-12-29",1793699839573]