一個TypeScript改造小例項
阿新 • • 發佈:2021-06-16
公司專案留下的JS程式碼,其中有一大段的switch/case (160行),正巧給組裡的同事介紹TypeScript,就順便拿這段switch/case做了個改造的例子。
原始程式碼(僅為示例)
var aHelper = { init: function() {...} } var bHelper = { init: function() {...} } var cHelper = { init: function() {...} } var Manager = { Step1: 0, Step2: 1, Step3: 2 initStep: function(stepNumber) { case this.Step1: aHelper.init(); bHelper.init(); cHelper.init(); break; case this.Step2: aHelper.init(); bHelper.init(); break; case this.Step3: bHelper.init(); cHelper.init(); break; } }
示例中的switch/case經過簡化,僅僅為了說明問題。TypeScript改造的目的是為了去除這些繁瑣的switch/case,程式碼如下:
interface IHelper { init: () => void; } class BaseHelper { color: string; } class ColorHelper extends BaseHelper implements IHelper { init() { console.log('init from ColorHelper'); } } class LensHelper extends BaseHelper implements IHelper { init() { console.log('init from LensHelper'); } } class RxHelper extends BaseHelper implements IHelper { init() { console.log('init from LensHelper'); } } enum StepType { Step1, Step2, Step3 } type StepTypeMapping = { [U in StepType]? : IHelper[] } // type StepTypeMapping = { // [U in StepType]? : string[] // } // const config: StepTypeMapping = { // [StepType.Step1] : ["ColorHelper", "LensHelper", "RxHelper" ], // [StepType.Step2] : ["ColorHelper", "LensHelper" ], // [StepType.Step3] : ["LensHelper", "RxHelper" ], // } const config: StepTypeMapping = { [StepType.Step1] : [new ColorHelper(), new LensHelper(), new RxHelper() ], [StepType.Step2] : [new ColorHelper(), new RxHelper() ], [StepType.Step3] : [new ColorHelper() ], } class StepManager { setStep(stepType: number) { config[stepType].forEach( helper => { helper.init(); //(eval("ColorHelper") as IHelper).init(); } ) } } const manager = new StepManager(); manager.setStep(StepType.Step1);
能想到的Config物件的實現方式有兩種,一種是通過String+eval動態生成例項(見程式碼中註釋掉的部分),一種是直接生成例項。