TypeScript的命令行安装:执行完下面命令行之后就可以在任何地方执行tsc命令了。
npm install -g typescript
当文件为ts后缀时, 执行命令 tsc xxx.ts 可以将文件转成js文件(同级目录下会新增一个xxx.js文件),再执行命令 node xxx.js就可以看到ts的执行结果
执行 tsc -watch后 可以达到实时编译的效果(修改ts文件,生成的js文件也会跟着被修改)
执行 tsc -init 会生成tsconfig.json 文件,可以对其配置进行修改
let a: string = 'a'
let a: number = 1
let a: boolean = true
let a: undefined = undefined
let a: null = null
数组有两种定义方式
// 元素类型后面接上 [],表示由此类型元素组成的一个数组
1. let list: number[] = [1, 2, 3]
// 使用数组泛型,Array<元素类型>
2. let list: Array<number> = [1, 2, 3]
interface aObj {
x: number;
y: string;
z?: Array<number>;
p?: number[]
}
function obj(a: aObj) {
}
// obj 这两种写法达到的效果是一样的
function obj(a: {x: number, y: string, z?: Array<number>, p?: number[]}) {
}
obj({x:2, y:'3', p: [1, 2, 3]})
// 使用类型别名 可以像定义对象那样定义变量类型
type objType = {
a: number;
b: string
}
function objTypeFun(a: objType) {
}
objTypeFun({a: 1, b: '1'})
// type也可以定义联合类型
type ID = number | string
function IDFun(id: ID) {
}
IDFun(1||'1')
// 类型别名type不能定义同名的, 区别于interface
type MyType = {
a: number;
}
type MyType = {
b: string
} // 这样写会报错 标识符“MyType”重复
// 通常接口首字母大写
interface Point{
x: number
y: string
}
// 接口 interface可以定义同名的, 区别于type
interface MyITF {
a: number;
}
interface MyITF {
b: string
} // 不会报错 使用的时候MyITF变量类型a, b两个属性都是必须的
如果只是单纯的定义变量类型,两种写法都可以,看个人喜好;
interface可以重复声明同名变量名称,type不行 会报错
如果考虑到扩展性的话,要用interface, eg:
interface Point { // 接口首字母大写
x: number
y: string
}
interface Zpoint extends Point {
z: number[]
}
function zpointFun(a: Zpoint) {
}
zpointFun({x:1, y:'1', z:[1,2,3]})
// 或者定义对象
const pointObj: Zpoint = {
x: 1,
y: '2',
z: [1, 2, 3]
}
// 其实类型别名也能扩展 eg:
type Zpoint = Point & {
z: number[]
}
const pointObj: Zpoint = {
x: 1,
y: '2',
z: [1, 2, 3]
}
// 使用联合类型之后 可以对其赋两种类型的值
let a: number | string = 1 || '1'
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 `string`和`number`类型的元组。
let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
类型断言有两种形式
// “尖括号”语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// as语法
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
as
语法断言是被允许的。字符串类型:
let aStr: 'hello' = 'hello' // 这样声明的类型为hello 值也必须为hello
type a2Str = {
a: string;
b: 'a' | 'b' | 'c', // 这样声明 b的值只能是a, b, c三种
}
const a2StrObj: a2Str = {
a: '1',
b: 'b'
}
function hhhh(p: a2Str | '哈哈哈') {}
hhhh('哈哈哈')
hhhh({a:'1', b: 'a'})
function position(e: string, align: 'left' | 'center' | 'right') { // 函数的第二个参数 值必须为left','center','right'
}
// 返回值推断
function compare(a: number, b:number): 0 | 1 { // 函数返回值必须是0 或 1
return a === b ? 1 : 0
}
enum Obj { // 当设置了a的值,后面b,c,d的值就在a的值上面递增1
a = 1,
b, // 2
c, // 3
d // 4
}
//注意:字符串枚举没有自增长行为,因此,字符串枚举的每个成员必须有初始值
某种程度上来说,void
类型像是与any
类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void
:
function warnUser(): void {
console.log("This is my warning message");
}
声明一个void
类型的变量没有什么大用,因为你只能为它赋予undefined
和null
:
let unusable: void = undefined;
never类型表示的是那些永不存在的值的类型。 例如, never
类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never
类型,当它们被永不为真的类型保护所约束时。
never
类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never
的子类型或可以赋值给never
类型(除了never
本身之外)。 即使 any
也不可以赋值给never
。
unknown类型代表任何值。这与any类型类似,但更安全,因为对未知unknown值做任何事情都是不合法的。
function fun1(a: any) {
a.b() // 可以
}
function fun2(a: unknown) {
a.b() // 不可以 会有错误提示
}
不用泛型:
function identity(arg: number): number {
return arg;
}
用泛型:
function identity<T>(arg: T): T {
return arg
}
使用: identity('huahua') || identity<string>('huahua')
// 多参数