精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Typescript 類型檢查原理之Override 是如何實現(xiàn)的

開發(fā) 前端
前段時間寫過一篇類型檢查的實現(xiàn)原理的文章,實現(xiàn)了簡單的賦值語句和函數調用的類型檢查。實際上類型檢查的情況特別多,一篇文章肯定寫不完,所以我準備用系列文章來講述各種類型檢查的實現(xiàn)原理,幫助大家更好的掌握 typescript。

[[403862]]

本文轉載自微信公眾號「神光的編程秘籍」,作者神說要有光 。轉載本文請聯(lián)系神光的編程秘籍公眾號。

前段時間寫過一篇類型檢查的實現(xiàn)原理的文章,實現(xiàn)了簡單的賦值語句和函數調用的類型檢查。實際上類型檢查的情況特別多,一篇文章肯定寫不完,所以我準備用系列文章來講述各種類型檢查的實現(xiàn)原理,幫助大家更好的掌握 typescript。

這一篇我們來實現(xiàn) 4.3 新增的 class 的 override 關鍵字的類型檢查。(源碼鏈接在后面)

override 修飾符是干嘛的

首先,我們來看下這個修飾符的作用:被 override 標示的方法必須得在父類中存在,否則會報錯。

  1. class Animal { 
  2.   getName() { return ''; } 
  3. class Dog extends Animal { 
  4.   override bak() { 
  5.     return 'wang'
  6.   } 
  7.   override getName() { 
  8.     return 'wang'
  9.   } 

上面這段代碼會報錯:This member cannot have an 'override' modifier because it is not declared in the base class 'Animal'.就是說重寫的放在父類不存在,這樣能避免父類重構的時候把一些子類需要重寫的方法給去掉。

如何實現(xiàn) override 修飾符的類型檢查

其實所有的修飾符,包括 override、public、static 等,在 parse 成 AST 后都是作為一個屬性存在的,這個 override 也是,我們通過 astexplorer.net 來查看一下。

可以看到 override 屬性為 true。這樣我們就可以通過這個屬性把該 class 的所有的需要 override 的 ClassMethod 過濾出來。

然后還可以拿到 superClass 的名字,從作用域中找到對應的聲明,然后遍歷 AST 找到它所聲明的所有 ClassMethod。

兩者對比一下,所有不在父類中的 ClassMethod 都需要報錯。

代碼實現(xiàn)

我們基于 babel 來做 parser 和分析,寫一個插件來做 override 的類型檢查。關于 babel 插件的基礎可以看小冊《babel 插件通關秘籍》。

開啟語法 typescript 插件來解析 ts 語法。

  1. const { transformFromAstSync } = require('@babel/core'); 
  2. const  parser = require('@babel/parser'); 
  3.  
  4. const ast = parser.parse(sourceCode, { 
  5.     sourceType: 'unambiguous'
  6.     plugins: ['typescript'
  7. }); 
  8.  
  9. const { code } = transformFromAstSync(ast, sourceCode, { 
  10.     plugins: [overrideCheckerPlugin] 
  11. }); 

插件要處理的是 ClassDeclaration,我們先搭一個基本的結構:

  1. const { declare } = require('@babel/helper-plugin-utils'); 
  2.  
  3. const overrideCheckerPlugin = declare((api, options, dirname) => { 
  4.     api.assertVersion(7); 
  5.  
  6.     return { 
  7.         pre(file) { 
  8.             file.set('errors', []); 
  9.         }, 
  10.         visitor: { 
  11.             ClassDeclaration(path, state) { 
  12.                 const semanticErrors = state.file.get('errors'); 
  13.                 //... 
  14.                 state.file.set('errors', semanticErrors); 
  15.             } 
  16.         }, 
  17.         post(file) { 
  18.             console.log(file.get('errors')); 
  19.         } 
  20.     } 
  21. }); 

具體的檢查邏輯是拿到父類的所有方法名,拿到當前類的所有 override 方法名,然后做下過濾。

我們首先要拿到父類的 ast,通過名字從作用域中查找。

  1. const superClass = path.node.superClass; 
  2. if (superClass) { 
  3.     const superClassPath = path.scope.getBinding(superClass.name).path; 

然后封裝一個方法來拿父類方法名,通過 path.traverse 來遍歷 ast,把收集到的方法名存到 state 中。

  1. function getAllClassMethodNames(classDeclarationNodePath) { 
  2.     const state = { 
  3.         allSuperMethodNames: [] 
  4.     } 
  5.     classDeclarationNodePath.traverse({ 
  6.         ClassMethod(path) { 
  7.             state.allSuperMethodNames.push(path.get('key').toString()) 
  8.         } 
  9.     }); 
  10.     return state.allSuperMethodNames; 

這樣就拿到了所有父類方法名。

之后需要拿到當前類的所有方法名并過濾出 override 為 true 且不在父類中的進行報錯。

  1. const superClass = path.node.superClass; 
  2. if (superClass) { 
  3.     const superClassPath = path.scope.getBinding(superClass.name).path; 
  4.     const allMethodNames = getAllClassMethodNames(superClassPath); 
  5.  
  6.     path.traverse({ 
  7.         ClassMethod(path) { 
  8.             if (path.node.override){ 
  9.                 const methodName = path.get('key').toString(); 
  10.                 const superClassName = superClassPath.get('id').toString(); 
  11.                 if (!allMethodNames.includes(methodName)) { 
  12.                     // 報錯                                     
  13.                 } 
  14.             } 
  15.         } 
  16.     }); 

報錯的部分使用 code frame 來創(chuàng)建友好的代碼打印格式,通過 Error.stackTraceLimit 設置為 0 去掉調用棧信息。

  1. const tmp = Error.stackTraceLimit; 
  2. Error.stackTraceLimit = 0; 
  3. let errorMessage = `this member cannot have an 'override' modifier because it is not declared in the base class '${superClassName}'`; 
  4. semanticErrors.push(path.get('key').buildCodeFrameError(errorMessage, Error)); 
  5. Error.stackTraceLimit = tmp; 

這樣,我們就完成了 override 的類型檢查,整體代碼如下:

  1. const { declare } = require('@babel/helper-plugin-utils'); 
  2.  
  3. function getAllClassMethodNames(classDeclarationNodePath) { 
  4.     const state = { 
  5.         allSuperMethodNames: [] 
  6.     } 
  7.     classDeclarationNodePath.traverse({ 
  8.         ClassMethod(path) { 
  9.             state.allSuperMethodNames.push(path.get('key').toString()) 
  10.         } 
  11.     }); 
  12.     return state.allSuperMethodNames; 
  13.  
  14. const overrideCheckerPlugin = declare((api, options, dirname) => { 
  15.     api.assertVersion(7); 
  16.  
  17.     return { 
  18.         pre(file) { 
  19.             file.set('errors', []); 
  20.         }, 
  21.         visitor: { 
  22.             ClassDeclaration(path, state) { 
  23.                 const semanticErrors = state.file.get('errors'); 
  24.  
  25.                 const superClass = path.node.superClass; 
  26.                 if (superClass) { 
  27.                     const superClassPath = path.scope.getBinding(superClass.name).path; 
  28.                     const allMethodNames = getAllClassMethodNames(superClassPath); 
  29.          
  30.                     path.traverse({ 
  31.                         ClassMethod(path) { 
  32.                             if (path.node.override){ 
  33.                                 const methodName = path.get('key').toString(); 
  34.                                 const superClassName = superClassPath.get('id').toString(); 
  35.                                 if (!allMethodNames.includes(methodName)) { 
  36.                                     const tmp = Error.stackTraceLimit; 
  37.                                     Error.stackTraceLimit = 0; 
  38.                                     let errorMessage = `this member cannot have an 'override' modifier because it is not declared in the base class '${superClassName}'`; 
  39.                                     semanticErrors.push(path.get('key').buildCodeFrameError(errorMessage, Error)); 
  40.                                     Error.stackTraceLimit = tmp;                                     
  41.                                 } 
  42.                             } 
  43.                         } 
  44.                     }); 
  45.                 } 
  46.                 state.file.set('errors', semanticErrors); 
  47.             } 
  48.         }, 
  49.         post(file) { 
  50.             console.log(file.get('errors')); 
  51.         } 
  52.     } 
  53. }); 
  54.  
  55. module.exports = overrideCheckerPlugin; 

github 鏈接

測試效果

我們用最開始的代碼來測試一下:

  1. class Animal { 
  2.     getName() { return ''; } 
  3. class Dog extends Animal { 
  4.     override bak() { 
  5.         return 'wang'
  6.     } 
  7.     override getName() { 
  8.         return 'wang'
  9.     } 

打印信息為:

正確的識別出了 bak 在父類不存在的錯誤。

至此,我們實現(xiàn)了 override 的類型檢查!

總結

類型檢查情況很多,所以需要一個系列文章去講,這一篇我們來實現(xiàn) override 的類型檢查。

override 是 ts 4.3 加入的特性,帶有 override 修飾符的方法必須在父類中有對應的聲明,否則會報錯。

我們通過 babel 插件的方式實現(xiàn)了類型檢查,思路是從作用域取出父類的聲明,然后通過 path.traverse 拿到所有方法名,之后再取當前類的所有方法名,對于沒在父類中聲明并且?guī)в?override 修飾符的方法進行報錯。

本文是 【typescript 類型檢查原理】系列文章的第二篇,后續(xù)還會有更多 typescript 類型檢查的實現(xiàn)原理揭秘的文章。希望能夠幫助大家更好的掌握 typescript。

關于 babel 插件的知識,可以看我的 babel 小冊《babel 插件通關秘籍》,其中有詳細的講解。

本文源碼鏈接 https://github.com/QuarkGluonPlasma/babel-plugin-exercize/tree/master/exercize-type-checker/src

 

責任編輯:武曉燕 來源: 神光的編程秘籍
相關推薦

2021-06-09 07:55:19

Typescript類型檢查

2022-04-11 08:42:09

TypeScript子類型定義

2009-07-22 09:43:30

Scala類型

2022-05-04 09:02:41

TypeScript類型工具

2020-12-18 11:35:22

TypeScript語言Java

2022-04-10 19:26:07

TypeScript類型語法

2022-09-14 15:24:57

typescript快排

2024-07-30 10:27:10

TypeScript配置TS

2012-07-02 10:43:49

JVMGroovyJava

2023-01-05 08:09:27

GroovyDSL?

2022-02-25 09:06:02

TypeScripnever工具

2021-07-27 06:06:34

TypeScript語言運算符

2023-06-13 18:24:26

TypeScriptJSDoc開發(fā)

2013-07-09 14:41:58

C動態(tài)類型

2021-08-18 07:56:05

Typescript類型本質

2024-05-11 10:19:31

TypeScript類型接口

2022-08-08 09:00:42

TypeScript映射類型

2022-02-09 08:11:50

架構

2025-11-03 06:43:19

數據庫垂直拆分用戶數據

2020-06-04 07:51:30

MySQL死鎖加鎖
點贊
收藏

51CTO技術棧公眾號

国产精品xxxx| 亚洲天堂一区二区三区| www.好吊操| 天天射天天操天天干| 欧美中文字幕| 日韩综合中文字幕| youjizz.com日本| 欧美18av| 一区二区三区四区中文字幕| 精品一区二区三区视频日产| 欧美 亚洲 另类 激情 另类| 国产精品99一区二区三区| 日韩三级av在线播放| 日韩av资源在线| av中文字幕在线播放| 91亚洲精品久久久蜜桃| 成人午夜两性视频| 亚洲精品午夜国产va久久成人| 日韩综合在线| 日韩av影视综合网| theporn国产精品| 欧美性xxx| 亚洲国产日韩一区二区| 亚洲高清视频一区| 天天综合天天色| 韩国av一区二区三区四区| 欧美诱惑福利视频| 久久国产一级片| 91久久夜色精品国产按摩| 亚洲精品wwww| 国产免费无码一区二区| 日韩第二十一页| 91久久国产综合久久| 欧美又粗又长又爽做受| 成人影院在线观看| 欧美韩日一区二区三区四区| 精品在线视频一区二区| 成人av手机在线| 极品少妇xxxx偷拍精品少妇| 国产精品露脸av在线| 丰满少妇乱子伦精品看片| 欧美在线影院| 不卡中文字幕av| 人人艹在线视频| 欧美人与物videos另类xxxxx| 亚洲成人国产精品| 午夜性福利视频| 欧美经典影片视频网站| 69久久夜色精品国产69蝌蚪网| 天天碰免费视频| 午夜欧美巨大性欧美巨大| 欧美日韩激情小视频| 在线视频不卡一区二区三区| 永久免费av片在线观看全网站| 久久久国际精品| 欧洲一区二区在线| 毛片网站在线| 国产日产欧美一区二区三区 | 91国产丝袜播放在线| 一区二区三区四区在线观看国产日韩| 日韩中文第一页| 免费观看特级毛片| 91中文字幕精品永久在线| 日韩在线小视频| 免费精品在线视频| 亚洲无中文字幕| 欧美成人精品不卡视频在线观看| 在线观看美女av| 黄色精品免费| 26uuu亚洲伊人春色| 少妇一级淫片免费放中国| 亚洲欧美日韩专区| 国产精品激情自拍| 在线播放国产一区| 国产在线国偷精品免费看| 91传媒在线免费观看| 丰满肉嫩西川结衣av| 91在线视频播放地址| 欧美亚州在线观看| a中文在线播放| 综合在线观看色| 久草免费福利在线| 欧美成人资源| 777午夜精品免费视频| 中文在线字幕观看| 日韩电影在线观看完整免费观看| 亚洲欧美在线磁力| www.com.av| 精品动漫3d一区二区三区免费版 | 亚洲天堂男人天堂| 亚洲波多野结衣| 亚洲日本成人| 国产精品麻豆va在线播放| 国产偷人妻精品一区二区在线| 成人av免费在线观看| 欧美日韩另类丝袜其他| 麻豆影院在线| 婷婷成人激情在线网| 成人性生生活性生交12| 天堂av一区| 亚洲午夜国产成人av电影男同| 91九色丨porny丨极品女神| 亚洲激情精品| 成人黄色短视频在线观看| 五月激情丁香婷婷| 亚洲欧洲日产国产综合网| 日韩精品一区在线视频| 成人四虎影院| 亚洲精品www| 疯狂试爱三2浴室激情视频| 日韩视频一区| 亚洲综合色激情五月| 欧美少妇另类| 香蕉久久一区二区不卡无毒影院| 三上悠亚在线一区二区| 群体交乱之放荡娇妻一区二区| 日韩一区二区欧美| 久久久免费高清视频| 国产成人高清在线| 一区二区不卡在线观看| 伊人久久精品一区二区三区| 精品日韩一区二区三区免费视频| jizz日本在线播放| 亚洲一区欧美激情| 国产精华一区| 亚洲婷婷噜噜| 欧美精品少妇一区二区三区| 实拍女处破www免费看| 国产精品激情电影| 成人国产精品久久久久久亚洲| 黄上黄在线观看| 欧美日韩国产综合新一区| 麻豆精品国产传媒| 久久精品久久久| 国产噜噜噜噜噜久久久久久久久 | 中文字幕资源网| wwww国产精品欧美| 日本欧美黄色片| 成人av动漫| 欧美另类交人妖| 99久久精品国产一区色| 中文字幕在线不卡一区| 9久久婷婷国产综合精品性色 | 欧美精品激情在线观看| 国产免费av电影| ●精品国产综合乱码久久久久| 爱情岛论坛成人| 奇米狠狠一区二区三区| 热99在线视频| 美国一级片在线免费观看视频 | 国产精品天美传媒| 欧美精品性生活| 青青草原综合久久大伊人精品| 国产国语videosex另类| 国产在线三区| 欧美视频在线一区| 美女100%露胸无遮挡| 青青草国产精品97视觉盛宴| 特级西西444www大精品视频| 99欧美精品| 久久精品99久久香蕉国产色戒| 亚洲最新av网站| 亚洲日本电影在线| gogo亚洲国模私拍人体| 欧美日韩三级| 国产尤物91| 日韩高清成人| 日韩在线中文视频| 亚洲av少妇一区二区在线观看| 亚洲一区二区三区四区的| 欧美双性人妖o0| 日韩精品欧美精品| 一区二区三区四区| 日韩高清二区| 992tv成人免费视频| 欧美美乳在线| 7777精品伊人久久久大香线蕉超级流畅 | 欧美区在线播放| 午夜国产在线观看| 91福利国产精品| 国产真实乱在线更新| 粉嫩aⅴ一区二区三区四区| 人妻少妇精品无码专区二区 | 亚洲色图35p| 亚洲综合五月天婷婷丁香| 一区二区三区精品久久久| 在线免费观看污视频| 日韩成人午夜电影| 91免费版看片| 网红女主播少妇精品视频| 国产精品人人做人人爽| 天堂av资源在线观看| 亚洲男人天堂古典| 国产裸体永久免费无遮挡| 亚洲成人tv网| 午夜精品久久久久99蜜桃最新版| 国产精选一区二区三区| 精品国产乱码久久久久软件| 久久久国产成人精品| 欧美极品少妇xxxxⅹ免费视频| 国产无码精品在线观看| 久久影院午夜片一区| 日本一区二区在线播放| 亚洲精品一区二区三区区别| 欧美性xxxxx极品| 日日噜噜夜夜狠狠久久波多野| 91丝袜呻吟高潮美腿白嫩在线观看| 视频在线观看免费高清| 国产日韩欧美三级| 亚洲国产精品影视| 免费视频国产一区| 国产精品日本一区二区| 91成人小视频| 国产精品成人久久久久| 波多野结衣视频一区二区| 伦伦影院午夜日韩欧美限制| 国产在线视频网| 日韩av在线网址| 亚洲AV无码国产精品午夜字幕 | av成人app永久免费| 国产精品高潮呻吟久久av野狼| 第一中文字幕在线| 久久国产精彩视频| yourporn在线观看中文站| 亚洲精品理论电影| 囯产精品久久久久久| 欧美精品在线一区二区| 成人免费一区二区三区| 一本大道综合伊人精品热热| 日韩成人av毛片| 一区二区三区蜜桃| 男女性高潮免费网站| 国产精品美女久久久久久久久久久 | 亚洲一区 二区| 国产美女久久精品| 日韩在线短视频| 国产成人精品日本亚洲| 中文字幕乱码中文乱码51精品| 欧美极品第一页| xxxx成人| 91精品国产91| 超碰激情在线| 97精品久久久| 美女扒开腿让男人桶爽久久软| 久久久免费高清电视剧观看| 国产亚av手机在线观看| 欧美极品在线播放| 日本乱理伦在线| 欧美精品www在线观看| 日本一本在线免费福利| 欧美黑人巨大精品一区二区| 亚洲妇熟xxxx妇色黄| 欧美久久久精品| 制服丝袜在线播放| 高清欧美性猛交| 国产在线观看www| 国产精品91在线| 欧美与亚洲与日本直播| 国产女同一区二区| 国产精品视频首页| 99porn视频在线| 卡通动漫精品一区二区三区| 你懂的网址一区二区三区| 国产精品亚洲二区| 中文字幕99| 国产精品v日韩精品v欧美精品网站| 阿v天堂2018| 亚洲影音一区| 五月天激情播播| 国产91精品一区二区| 在线免费播放av| 久久精品一区二区三区不卡| 久久视频一区二区三区| 亚洲天堂a在线| 国产香蕉在线视频| 色诱视频网站一区| 91麻豆成人精品国产| 日韩欧美国产系列| 天堂影院在线| www国产精品视频| 激情影院在线| 青青青国产精品一区二区| 久久婷婷五月综合色丁香| 97av影视网在线观看| 亚州av日韩av| 欧美aaa在线观看| 国产欧美丝祙| 成人日韩在线视频| 成人精品gif动图一区| 谁有免费的黄色网址| 亚洲色图第一区| 性无码专区无码| 91精品欧美一区二区三区综合在| 香蕉av在线播放| 日韩中文字幕欧美| 999av小视频在线| 国产日韩欧美黄色| 天堂综合网久久| 麻豆一区二区三区在线观看| 国产欧美一区二区色老头| 中文字幕 日韩 欧美| 99视频一区二区三区| 久久精品一区二区三区四区五区 | 国产麻豆91视频| 亚洲精品午夜精品| 三级资源在线| 国产精品一区二区三| 任你躁在线精品免费| 久久久久久久久网| 热久久久久久久| 精品无码人妻一区| 亚洲成av人综合在线观看| 91久久久久国产一区二区| 亚洲色图综合久久| 激情黄产视频在线免费观看| 91视频免费进入| 欧美freesextv| 狠狠操精品视频| 97se狠狠狠综合亚洲狠狠| 久久久久久国产精品视频 | 日本久久精品视频| 亚洲国产精品免费视频| 亚洲一区影院| 三级亚洲高清视频| 亚洲av片不卡无码久久| 亚洲资源中文字幕| 国产伦精品一区二区三区视频痴汉| 亚洲欧洲第一视频| 欧美激情护士| 国产欧美一区二区视频| 欧美精品18| 无套白嫩进入乌克兰美女| 国产精品免费视频观看| 欧美三级网站在线观看| 亚洲摸下面视频| 天堂中文在线播放| 麻豆av一区| 国产精品久久777777毛茸茸| 亚洲色偷偷色噜噜狠狠99网| 一区二区三区欧美| 午夜精品在线播放| 欧美老女人性生活| 综合成人在线| 国产av熟女一区二区三区| 久久狠狠亚洲综合| 成人欧美一区二区三区黑人一| 欧美性色欧美a在线播放| 国产理论电影在线观看| 国产精品第1页| 欧美亚洲在线日韩| 9l视频白拍9色9l视频| 国产精品福利一区二区| 亚洲一区二区激情| 久久亚洲精品小早川怜子66| 国产精品欧美一区二区三区不卡| 国产对白在线播放| 国产成人综合自拍| 久久精品欧美一区二区| 亚洲国产日韩欧美在线图片| 极品在线视频| 日韩精品欧美一区二区三区| 老鸭窝一区二区久久精品| 99久久婷婷国产综合| 日韩美女视频在线| 成年男女免费视频网站不卡| 欧美18视频| 免费观看在线综合色| 日韩三级久久久| 精品成人在线观看| 亚洲精品中文字幕| 天天综合色天天综合色hd| 狠狠色伊人亚洲综合成人| 久久免费少妇高潮99精品| 日韩av最新在线观看| 本网站久久精品| 国产内射老熟女aaaa| 91亚洲精品久久久蜜桃网站 | 一区视频二区视频| 国产精品456露脸| 欧美在线观看不卡| 色偷偷噜噜噜亚洲男人的天堂| 亚洲综合影院| 国产三级日本三级在线播放| 亚洲天堂成人网| 九色在线视频蝌蚪| 亚洲一区二区三区久久| 国产精品美女久久久浪潮软件| 少妇视频一区二区| 亚洲精品久久久久| 亚洲精品66| 激情深爱综合网| 亚洲欧洲日韩女同| 午夜在线视频观看| 91在线观看欧美日韩| 免费在线成人| www.99re7| 国产亚洲欧洲高清| 国产精品久久久久av蜜臀| 男人搞女人网站| 香蕉成人啪国产精品视频综合网 |