一、declare关键字
declare:就是告诉TS编译器你担保这些变量和模块存在,并声明了相应类型,编译的时候不需要提示错误
二、Vue3中报错不能将类型string分配给类型Ref<string>
const realtime = ref('');
realtime='errui'; //报错
//取值的时候ref只有唯一的属性value,想要赋值必须加上value
realtime.value='errui';//正确
三、const 断言
const x = { text: "hello" } as const;
TypeScript 3.4 引入了一个名为 const 断言的字面值的新构造。它的语法是一个类型断言,用 const 代替类型名称(例如 123 as const)断言构造新的文字表达式时,我们可以向语言发出以下信号:
该表达式中的字面类型不应被扩展(例如:不能从“hello”转换为字符串)
例子:CountActions 是这两个接口的联合。
const setCount = (n: number) => {
return <const>{
type: "SET_COUNT",
payload: n,
};
};
const resetCount = () => {
return <const>{
type: "RESET_COUNT",
};
};
type CountActions = ReturnType<typeof setCount> | ReturnType<typeof resetCount>;
我们从 action creator 函数 setCount 和 resetCount 的返回类型中推断出一个很好的 action 联合。
四、类型断言
手动指定一个值的类型
语法: 值 as 类型
或 <类型>值
1、类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误,反而滥用类型断言可能会导致运行时错误
interface Cat {
name: string;
run(): void;
}
interface Fish {
name: string;
swim(): void;
}
function swim(animal: Cat | Fish) {
(animal as Fish).swim();
}
const tom: Cat = {
name: 'Tom',
run() { console.log('run') }
};
swim(tom);
// Uncaught TypeError: animal.swim is not a function`
2、将一个父类断言为更加具体的子类
interface ApiError extends Error {
code: number;
}
interface HttpError extends Error {
statusCode: number;
}
function isApiError(error: Error) {
if (typeof (error as ApiError).code === 'number') {
return true;
}
return false;
}
3、将任何一个类型断言为 any
一方面不能滥用 as any,另一方面也不要完全否定它的作用,我们需要在类型的严格性和开发的便利性之间掌握平衡(这也是 TypeScript 的设计理念之一),才能发挥出 TypeScript 最大的价值。
五、keyof操作符
keyof操作符:是将一个类型映射为它所有成员名称的联合类型。
interface Person {
name: string;
age: number;
gender: string;
}
type P = keyof Person; // "name" | "age" | "gender"
// 我们可以看到,keyof将Person这个对象类型映射成了一个联合类型
// 因此我们可以更方便的操作这个联合类型
也可以写的复杂点用泛型继承/扩展类型
class Student {
constructor(private info: Person) {}
getInfo<T extends keyof Person>(key: T): Person[T] {
return this.info[key];
}
}
// T是泛型,通过keyof得到了Person的成员名的联合类型,即"name" | "age" | "gender"
// 这样就实现了限制key值的输入,这时候key只能输入"name" | "age" | "gender"
// 而也不会出现返回结果为undefined了
六、typeof操作符
typeof操作符: 在编译时获取类型
interface Person {
name: string,
age: number,
}
let person: Person = { name: 'tao', age: 18 }
//两者一样
type p1 = typeof person
type p2 = Person
七、interface来定义函数的形状
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。
扩展泛型接口
也可以使用含有泛型的接口来定义函数的形状:
interface CreateArrayFunc {
<T>(length: number, value: T): Array<T>;
}
let createArray: CreateArrayFunc;
createArray = function<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray(3, 'x'); // ['x', 'x', 'x']
八、将lib编译器选项同时设置为dom和dom.iterable是否多余
dom.iterable向各种domapi添加了iterables的定义。如果您使用的是带有domapi的运行时环境,那么应该包含dom定义。如果您使用的运行时环境支持各种domapi上的iterable方法,那么您将包括dom.iterable。在使用运行时环境时,如果在具有iterable方法的DOM API上支持iterable方法,则将dom本身包括在内,这意味着您在尝试访问这些iterable方法时将出现类型错误。单独包含dom.iterable将不起作用,因为它会增加dom定义。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。