TypeScript问题汇总

标签: 无 分类: 未分类 创建时间:2023-03-27 02:11:13 更新时间:2024-11-12 12:53:37

前言

参考文章:
1.声明文件

1.Could not find a declaration file for module

“无法找到模块的声明文件” 这个就是因为文件不是ts文件

【解决方法】
1.如果有这个包的 ts 版本,安装ts版本

2.找到根目录下的 shims-vue-d.ts 文件,增加模块声明。如果没有 shims-vue-d 这个文件,那就找env.

1
2
3
4
5
6
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
// 加上这个
declare module 'xxx'

3.如果不在乎外部库的类型,可以直接设为

1
declare module '*'

2.Property ‘xxx’ does not exist on type ‘{}’

这个主要就是在调用某一个函数的时候出现这个错误提示,表明属性或者方法不存在,声明的 d.ts 文件中不包含这个属性或者方法。

【解决方法】
查看 d.ts 文件中声明的内容,是否包含了这个属性,并进行修改。

3.property xxx does not exist on type Object

不同于上面的那种报错,这个主要发生在使用一个对象作为参数的时候,会发生的事情。这是因为Typescript在执行代码检查时在该对象没有定义相应属性,遇到该报错有以下几种解决方式:

(1) 将对象类型设置为any

(2) 通过字符方式获取对象属性

1
2
var obj: Object = Object.create(null);
obj["xxx"] = "xxx";

(3) 通过接口定义对象所具有的属性

1
2
3
4
5
6
var obj: xxxObject = Object.create(null);
obj.xxx= "xxx";

interface xxxObject {
xxx?: string
}

(4) 使用断言强制执行

1
2
var obj: Object = Object.create(null);
(obj as any).xxx= "xxx";

4.Object literal may only specify known properties

在使用对象字面量的时候:“Argument of type ‘{ key: string; name: string; }’ is not assignable to parameter of type ‘any[]’. Object literal may only specify known properties, but ‘key’ does not exist in type ‘any[]’. Did you mean to write ‘keys’”。

当对象字面量中的属性在对象类型中不存在时,会发生“Object literal may only specify known properties”错误。 要解决该错误,请确保键入对象的所有属性并修复属性名称中的拼写错误(如果有)。例如:

1
2
3
4
5
6
type Employee = {
id: number;
name: string;
};

const emp: Employee = { id: 1, name: 'Alice' };

5.声明文件的继承和扩展

就是说在别人写的d.ts文件的基础上增加自己的内容。

6.Cannot find module ‘vue’ or its corresponding type declarations

在一个工程的 .d.ts 文件中,写了一段模块声明,这里的import,总是弹出上面的问题。

1
2
3
4
5
6
declare module "*.vue" {
import { DefineComponent } from "vue"
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

【尝试】
1.我尝试了安装vue的声明文件,无效

1
pnpm add -D @types/vue

2.重启了vscode,无效

【解决方法】
后来我修改了import的位置,解决了这个错误提示

1
2
3
4
5
6
7
8
// 将引入改到了这里
import { DefineComponent } from "vue"

declare module "*.vue" {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

7.Property ‘map’ does not exist on type ‘Window & typeof globalThis’

这个主要是在 window 上挂载不存在的属性导致的错误。

【尝试】
1.尝试在env.d.ts文件中定义Window接口,无效

1
2
3
4
5
6
7
/**
* 给 window 挂载属性
*/
import * as mars3d from "mars3d"
interface Window {
map: mars3d.Map;
}

2.尝试使用方括号的形式访问,出现了:“Element implicitly has an ‘any’ type because index expression is not of type ‘number’”

1
window["map"] = map

【解决方法】
这个方法主要就是在 env.d.ts 文件中增加如下的内容,除了声明interface之外,还要 declare global。这样就算是使用 window[“map”] 也不会报错了。

1
2
3
4
5
6
import * as mars3d from "mars3d"
declare global { //设置全局属性
interface Window { //window对象属性
map: mars3d.Map;
}
}

还有种情况,就是连这个 env.d.ts 文件都无效。你在项目的根目录下创建了一个 env.d.ts 声明了上面的代码,本意就是要取消这个 map 变量不存在的警告,结果还是出现了。这个时候就要考虑是不是这个 env.d.ts生效了。需要在tsconfig.json文件中,通过 include 包含这个 env.d.ts 文件,比如我这里使用了 .d.ts 代替。 如果这个 。d.ts 放到了 src目录下,那就要在 include 中包括 “src//*.d.ts” 路径。

1
2
3
4
{

"include": ["packages/**/*.ts", "*.d.ts","src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
}
参考文章:
1.完美解决:Property ‘XXX‘ does not exist on type ‘Window‘ Typescript complains that you do not have the property inside the data, you can either use any or create an inteface with that property。这里在全局上处理,会导致问题出现。
2.Typescript给window对象添加全局变量 interface Window,这里说:declare global { interface Window } 实际上这个方法在typescript 3.4之后就无效了
3.引用window自定义变量以及ts在window上自定义变量数据类型报错的解决方案
4.vscode报错:找不到.d.ts中定义的名称 这里使用的是 include 文件夹包裹进来了。
5.React中使用window全局变量出现“Property ‘xx‘ does not exist on type ‘Window & typeof globalThis‘.“ 在src目录下创建一个global.d.ts文件

8.VSCode中的typescript版本

在解决上面一个问题的时候,我发现了新版和旧版的typescript可能在写法上有些区别,所以我就想着,要在vscode中,可以查看到typescript的版本。
(1) 选中一个.ts文件
(2) 点击右下角ts版本,鼠标放到那个Typescript前面的中扩号下,就可以出现版本选择了,可以看到我现在的typescript版本是4.9.5版本

(3) 选择使用工作区版本,会在项目根目录中生成一个.vscode/setting.json文件

(4) .vscode/setting.json文件内容如下:

1
2
3
{
"typescript.tsdk": "node_modules/typescript/lib"
}
参考文章:
1.如何在VSCode中切换typescript的版本,使用工作空间的版本
2.如何修改 Visual Studio Code 內建的 TypeScript 版本 只要有用到 Decorators 的地方,就會出現這個警示訊息,從錯誤訊息中可以得知,這個 Decorators 其實還是一個實驗性的功能,他未來可能會被加到 ECMAScript 2016 (ES7) 規格中,只是目前這份規格尚未推出正式版,因此才會顯示這個警告。只要到 tsconfig.json 設定 experimentalDecorators 為 true,照理說就可以消除這個錯誤訊息
3.VSCode中切换TS版本 typescript工程中会会使用默认的TS版本,该版本通常是VSCode中自带的版本(但版本可能会比较旧),
这时通常需要切换到项目中依赖的TS版本
4.一觉睡醒,我vscode里的TypeScript项目全报错了 vscode更新的时候,vscode本地使用的TypeScript也会更新(如果有新版本的话),vscode本地使用的ts版本,与我们项目中的ts版本很可能不一致。在Workspace Settings(JSON)中配置”typescript.tsdk”: “./node_modules/typescript/lib”,让vscode能找到项目中node_modules里安装的TypeScript版本。

9.不能将类型“null”分配给类型“NodeListOf

为了清空 dom 引用,一般将 dom 使用完成之后,直接等于null, 浏览器就会释放,但是在typescript中,这里就会报错。

1
2
3
4
5
6
7
8
9
10
11
12
onst menuActive = (name) => {
let menus = document.querySelectorAll('.menu-item');
menus.forEach((item) => {
if (item.classList.contains('item-' + name)) {
item.classList.add('active');
} else {
item.classList.remove('active');
}
});
// 出问题的代码
menus = null;
};
参考文章:
1.TypeScript——不能将类型“HTMLElement | null”分配给类型“HTMLElement”
2.Why is delete not allowed in Javascript5 strict mode? The delete statement is still allowed in strict mode, but some particular uses of it are erroneous. It’s only allowed for object properties, not simple names, and only for object properties that can be deleted.

10.“+”运算符不能应用于类型 “symbol”

可以使用 toString() 方法将 Symbol 类型进行转换。

1
'main-' + routeName?.toString()
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。