Angular项目执行yarn install后Storybook构建报TS类型错误
yarn install后Storybook构建失败的TypeScript错误 错误信息
node_modules/@storybook/api/dist/ts3.9/modules/shortcuts.d.ts:55:18 - error TS2430: Interface 'Event' incorrectly extends interface 'KeyboardEvent'.
ERR! Types of property 'target' are incompatible.
ERR! Property 'prototype' is missing in type '{ tagName: string; addEventListener(): void; removeEventListener(): boolean; dispatchEvent(event: Event): boolean; getAttribute(attr: string): string | null; }' but required in type 'EventTarget'.
ERR!
ERR! 55 export interface Event extends KeyboardEvent {
ERR! ~~~~~
ERR!
ERR! node_modules/typescript/lib/lib.dom.d.ts:5144:5
ERR! 5144 prototype: EventTarget;
ERR! ~~~~~~~~~
ERR! 'prototype' is declared here.
项目配置
package.json
{ "name": "tour", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "docs:json": "compodoc -p ./tsconfig.json -e json -d .", "storybook": "npm run docs:json && start-storybook -p 6006", "build-storybook": "npm run docs:json && build-storybook" }, "private": true, "dependencies": { "@angular/animations": "^14.1.0", "@angular/common": "^14.1.0", "@angular/compiler": "^14.1.0", "@angular/core": "^14.1.0", "@angular/forms": "^14.1.0", "@angular/platform-browser": "^14.1.0", "@angular/platform-browser-dynamic": "^14.1.0", "@angular/router": "^14.1.0", "rxjs": "~7.5.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "^14.1.0", "@angular/cli": "~14.1.0", "@angular/compiler-cli": "^14.1.0", "@babel/core": "^7.19.3", "@compodoc/compodoc": "^1.1.19", "@storybook/addon-actions": "^6.5.12", "@storybook/addon-essentials": "^6.5.12", "@storybook/addon-interactions": "^6.5.12", "@storybook/addon-links": "^6.5.12", "@storybook/angular": "^6.5.12", "@storybook/builder-webpack5": "^6.5.12", "@storybook/manager-webpack5": "^6.5.12", "@storybook/testing-library": "^0.0.13", "@types/jasmine": "~4.0.0", "babel-loader": "^8.2.5", "jasmine-core": "~4.2.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.0.0", "typescript": "~4.7.2" } }
angular.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "tour": { "projectType": "application", "schematics": {}, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/tour", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.css" ], "scripts": [] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "outputHashing": "all" }, "development": { "buildOptimizer": false, "optimization": false, "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "browserTarget": "tour:build:production" }, "development": { "browserTarget": "tour:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "tour:build" } }, "storybook": { "builder": "@storybook/angular:start-storybook", "options": { "browserTarget": "tour:build", "port": 6006 } }, "build-storybook": { "builder": "@storybook/angular:build-storybook", "options": { "browserTarget": "tour:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.css" ], "scripts": [] } } } } } }
可能的原因及解决思路
核心原因
这个错误是Storybook 6.5.x版本与TypeScript 4.7.x的类型定义冲突导致的:@storybook/api中自定义的Event接口继承了KeyboardEvent,但它定义的target类型缺少DOM标准EventTarget要求的prototype属性,和TypeScript内置的DOM类型库冲突。
另外,执行yarn install后可能拉取了某些间接依赖的更新,触发了原本隐藏的兼容性问题。
解决方法
- 锁定Storybook依赖版本:把package.json中所有
@storybook/开头的依赖版本号前的^去掉(比如^6.5.12改成6.5.12),然后重新执行yarn install,避免间接依赖自动升级。 - 降级TypeScript版本:将
typescript版本从~4.7.2调整为~4.6.4,Storybook 6.5.x对TS 4.6的兼容性更稳定,同时也能适配Angular 14。 - 临时跳过库类型检查:在项目的
tsconfig.json的compilerOptions里添加"skipLibCheck": true,跳过第三方库的类型检查,快速恢复构建,但这是临时方案,不推荐长期使用。 - 升级到Storybook 7.x:Storybook 7.x重构了类型系统,对Angular 14和TS 4.7的兼容性更好,但升级需要调整部分配置(比如移除旧的webpack5相关依赖,适配新的Storybook配置方式)。
内容的提问来源于stack exchange,提问作者Tomislava

