Typescript 给 JavaScript 带来了强大的类型系统
类型语言: duck typing
所谓看起来像鸭子的就是鸭子类型;比如: 当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子
package main
import (
"fmt"
)
type ISayHello interface {
SayHello()
}
type Person struct {}
func (person Person) SayHello() {
fmt.Printf("Hello!")
}
type Duck struct {}
func (duck Duck) SayHello() {
fmt.Printf("ga ga ga!")
}
func greeting(i ISayHello) {
i.SayHello()
}
func main () {
person := Person{}
duck := Duck{}
var i ISayHello
i = person
greeting(i)
i = duck
greeting(i)
}
// 最后输出: Hello! ga ga ga
一: 基础类型
// 基础类型:
let num: number;
let str: string;
let bool: boolean;
num = 123;
num = 123.456;
num = '123'; // Error
str = '123';
str = 123; // Error
bool = true;
bool = false;
bool = 'false'; // Erro
// 数组
let boolArray: boolean[];
boolArray = [true, false];
console.log(boolArray[0]); // true
console.log(boolArray.length); // 2
boolArray[1] = true;
boolArray = [false, false];
boolArray[0] = 'false'; // Error
boolArray = 'false'; // Error
boolArray = [true, 'false']; // Error
在 TypeScript 中,还存在一些特殊的类型,它们是
any
、null
、undefined
以及void
二: 函数签名
//箭头函数签名
const simple: (foo: number) => string = foo => foo.toString();
// 函数重载
function stringOrNumber(foo: number): number;
function stringOrNumber(foo: string): string;
function stringOrNumber(foo: number | string): number | string {
if (typeof foo === 'number') {
return foo * foo;
} else if (typeof foo === 'string') {
return `hello ${foo}`;
}
}
// 函数参数的签名: default argument | options argument | reset argument
function fn(a: number, b: string, c: boolean = false, ...reset: number[]): void { }
三: 类型别名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n;
}
else {
return n();
}
}
四: interface
接口是 TypeScript 的一个核心知识,它能合并众多类型声明至一个类型声明: interface 可以约束多个属性集合, 也可以看做是一个
类型对象
的; 其中声明一个类对象应该具有哪些属性; 同时 interface 在类型系统中, 是可以被继承
, 同时也可以被多继承
; 这个和 java 中的 interface 具有相同的特点; 但是在 golang 中的 interface 和现在主流的强类型语言的 interface 是不一致的, golang 中的interface 是方法的集合;同时也可以声明为任意类型, 如果和这里的 any 类似
// 使用 interface 关键字来声明一个接口类型;
// 使用 interface 声明一个函数类型
interface ReturnString {
(): string;
}
const fn: ReturnString = () => {
return ""
}
// 使用 interface 声明一个可实例化的类型
interface Constructor {
new (): void;
}
let A: Constructor
const a = new A()
// 使用 interface 声明属性
interface Personal {
name: string
age: number
say?:() => string
[key: string]: any
}
// interface 的继承
interface BaseModel {
id: number
createAt: number
updateAt: number
}
// 单继承
interface UserModel extends BaseModel {
name: string
age: string
}
// 多继承
interface UserProfile extends UserModel, BaseModel{
}
// interface 被实现(implements)
interface DialogInter<T extends string> {
title: T
show: () => void
hide: () => void
}
export class InputDialog implements DialogInter {
public show!: () => void
public hide!: () => void
}
类型别名 vs interface
interface 会在类型系统中产生一个名字, 但是类型别名不会
五:类型断言
TypeScript 允许你覆盖它的推断,并且能以你任何你想要的方式分析它,这种机制被称为「类型断言」。TypeScript 类型断言用来告诉编译器你比它更了解这个类型,并且它不应该再发出错误。 同时我们也不是可以无脑来进行 as 来进行类型断言, 因为在 ts 认为你在做的一个必定错误的类型断言的时候, 会给 error; 类型断言是从一个类型转换到另一个类型, 如果 ts 无法进行转换, 就会出现
error
interface Foo {
bar: number;
bas: string;
}
const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';
六: 泛型
设计泛型的关键目的是在成员之间提供有意义的约束, 泛型只能出现在下面的地方
* 类的实例成员
* 类的方法
* 函数参数
* 函数返回值
// 创建一个泛型类,
// 泛型可以使用 extends 关键字来约束, 同时也可以给默认值
class Queue<T = any> {
private data :T[] = [];
push = (item: T) => this.data.push(item);
pop = (): T | undefined => this.data.shift();
}
七: 类型推导
TypeScript 能根据一些简单的规则推断(检查)变量的类型
let foo = 123; // foo 是 'number'
let bar = 'hello'; // bar 是 'string'
foo = bar; // Error: 不能将 'string' 赋值给 `number`
// 对函数放回值的推导
function add(a: number, b: number) {
return a + b;
}
// 这里使用泛型加 interface 来实现 ts 的类型推导
interface UserInfo {
name: string
age: number
}
function fn<T extends keyof UserInfo>(key: T, name: UserInfo[T]) {
}
它是如何提高我写代码的效率的
> 这里给出一个我的项目, ts 让我无脑写代码, 它会让我减少了大量的低级错误, 减少了大量的 debug 时间, 我们都知道我们开发业务需求大量时间都是在调试, debug; ts在写代码和调试上都大大减少了时间, 同时我不需要运行我都能看得懂我一个月前写的代码, 这个很神奇; 这里有一个我配置的 ts 项目代码; 其中的约束个人觉得做的还是可以的;
有疑问加站长微信联系(非本文作者)