前言
在时隔好久之后,终于开始学习Typescript了,很多朋友都推荐使用 TS,所以就想学一下,但看了一些分享,有位友友说使用TS最重要的就是除了添加类型之外,不要做任何额外的事情,不要让自己误以为这不是JavaScrpit!好~ 好 ~好 ~

TS和JS都有的类型
JS类型(七上八下):
- 七种基本类型:number,string,null,undefind,boolean,symbol,bigint
- 复杂数据类型:object
TS作为js的超集这些类型在ts中也都存在。
TS特有的类型
any:当值的类型为any时,可以访问该对象的任何属性,即使有些属性不存在,其在编译时也不会报错。 这就是为什么有些友友说既然🐶老板一直催那就别怪我全any了! BUT这只是开玩笑,在实际开发中我们要避免使用any
ini
let obj: any = { x: 0 };
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;
可以看到当我们将变量obj设置为any类型时,在调用或赋值其时尽管有些属性和方法不存在ts也不会给我们错误提示。
还有一种和any类似的
unknow
:被誉为安全版的any,unknow表示还未确定,两者都是可以控制任何类型,但是在对unknow操作之前必须先类型缩小才能安全使用。
ini
let x: unknown ;
let y: any;
x=10;
y=10;
x.toString();
y.toString();

ini
if(typeof x==="number"){
x.toString();
}
在做类型缩小之后就不会报错了。
也可以类型断言
(x as number).toString();
使用类型
在TS中无论何时声明变量和函数都可以在变量名和函数名后面使用:{type}格式注释其类型。
js
let username: string = 'Chris';
const myName = (name: string) => {
console.log(`Hello ${name}`);
};
但也不必明确指定username
的类型,TS其足够智能,它可以自动判断username
的类型。
可以看到当
username
的类型没有明确规定时,TS也知道发生了什么,可以给出调用中的错误。
我们还可以设置函数返回的数据类型通过在函数后面:{type}来定义函数返回值。
ts
const numberToString = (number: number): string => {
return number.toString();
};
const output = numberToString(123);
我们有一个函数接收一个类型为number
的参数,返回一个string
类型的值。 值得注意的是 :我们知道在js中就算没有设置函数返回值,其也会隐式返回undefined
javascript
function name(person){
}
console.log( typeof(name("Bob")));
而在TS中有个特殊的类型
void
: 用于函数无返回值,且调用该函数不会用到其返回值。我们知道在TS代码在编译的时候类型会被全部删掉,那么也就是说设置函数的返回值void,在编译为js代码时类型仍然是undefined。那么这二者有什么区别吗?
void
在TS中的作用通常起标记的作用,告诉你或其他同事该函数不会有返回值,不用调用它。其一般用于函数签名、回调函数 和 类型安全 场景中。
再来看一个例子:
ts
const getFullName = (user: {firstname: string, lastname: string}): string => {
return `${user.firstname} ${user.lastname}`;
};
getFullName({firstname: 'Chris', lastname: 'Bongers'});
在这里我们给函数传了一个user对象其有两个参数-姓和名,但有些时候我们只知道名不知道姓那要如何调用这个函数呢?
使类型可选
typescript
const getFullName = (user: {firstname: string, lastname?: string}): string => {
return `${user.firstname} ${user.lastname}`;
};
我们可以在:
前面加上问号,使类型成为可选的。 需要注意的是,默认情况下,变量是必需的。我们必须明确指出哪些变量是可选的。
如果我的变量有多种类型怎么办?
联合类型 :我们可以使用管道|
选项来定义这些联合类型。
typescript
const getUserId = (id: number | string) => {
return `Your ID is ${id}`;
};
getUserId(123);
getUserId('Chris123');
就比如我们的id有些时候可能是数字也可以是字符串,这时候就可以使用联合类型来定义一个包含多个元素类型的变量。
值得注意的是因为联合类型由两个或多个类型组合而成,其值可以是该联合类型的任意一个,但对该属性使用方法时不能使用其仅在一种类型才有用的方法,如toUpperCase()是string上的number并没有,所以这两种类型的联合类型不能使用。
类型别名
我们通过直接在类型注解中编写对象类型和联合类型来使用它们。 这很方便,但是常常会想要多次使用同一个类型,并且通过一个名称引用它。
typescript
type Person {
name: string;
age: number;
}
类型别名其灵活度非常高,可以别名任何类型:对象,数组,函数都可以别名
与之类似的定义对象结构的方法--接口(interface)看起来很像,但其实各有特点,适用场景也略有不同。
接口
typescript
interface Person {
name: string;
age: number;
}
在定义的时候几乎一样,但是接口可以继承,对于同名的接口TS会自动合并,但接口只能用于对象结构。
对比项 | interface |
type |
---|---|---|
是否能扩展/继承 | ✅ extends |
✅ 用交叉类型(& ) |
是否能声明合并 | ✅ | ❌ |
能否定义联合类型 | ❌ | ✅ |
能否表示函数、元组等非对象结构 | ❌ | ✅ |
更推荐用在哪 | 定义"对象结构"、接口扩展 | 联合类型、函数、类型组合等 |
最后补充一下
是否为函数和方法添加返回类型注解取决于代码作者。审阅者可能会要求使用注解来阐明难以理解的复杂返回类型。项目可能有本地策略要求始终提供返回类型,但这并不是 TypeScript 风格的通用要求。
明确输入函数和方法的隐式返回值有两个好处:
- 更精确的文档有利于代码的读者。
- 如果代码发生变化,改变了函数的返回类型,那么将来潜在的类型错误就会更快地显现出来。