Typescript语法入门

最近公司项目开始统一使用Typescript了,所以自己也是开始认真的学习了一下typescript,还是很有收获的!下面分享给大家

基础知识

  1. 基础
let isDone: boolean = false;

let decimal: number = 6;

let color: string = "blue";

// 数组,有两种写法
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

// 元组(Tuple)
let x: [string, number] = ["hello", 10];
// 元组类型是一个不可变的数组,长度、类型是不可变的。

// 当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型
x.push('123')
x.push(123)
x.push(true)   // error, 不能添加非字符串和 number 的值

// 枚举  通过enum则不能修改定义好的值了 
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
//  const Color1 = { Red: 1, Green: 2, Blue : 4}
//  上面Color1可以修改里面的值 例如Color.Red = 5; 枚举就无法修改了

//枚举的成员从0开始递增,并且key 和 value 会互相映射
enum Colors { Red, Yellow, Blue }
Colors['Red'] === 0 // true  从0开始递增
Colors[0] === 'Red' // 相互映射

// 枚举事实上会编译成如下
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Yellow"] = 1] = "Yellow";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));


// 不确定的可以先声明为any
let notSure: any = 4;

// 声明没有返回值
function warnUser(): void {
    alert("This is my warning message");
}

let u: undefined = undefined;

let n: null = null;

// 类型永远没返回
function error(message: string): never {
    throw new Error(message);
}

// 类型主张,就是知道的比编译器多,主动告诉编译器更多信息,有两种写法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;

  1. 封装
private/protected/public
  1. interface 接口
interface SystemConfig {
    attr1: string;
    attr2: number;
    func1(): string;
    func2(): void;
}
<!-- 我们给软件定了一个系统参数的配置接口,他定义了系统配置的形状,有两个属性attr1和attr2,两个方法func1和func2,这样如果定义了const systemConfig: SystemConfig = {},那systemConfig就不能随意修改了,他有形状了。 -->

也可以用implements来实现接口,这样可以实现类似更为灵活的继承,如:

class A extends BaseClass implements BaseInterface1, BaseInterface2 {}

<!-- 类A继承了BaseClass,并且继承了BaseInterface1和BaseInterface2两个接口 -->
// 接口也是可以继承接口的
interface Fa {
  surname: string
}

interface Son extends Fa {
  name: string
}

const obj: Son = {
  surname : 'z',
  name: 'zc'
}

class Fa {
  constructor() {}
  suck(){

  }
}

interface Son extends Fa {
  suck():void;
  name: string;
}
  1. 命名空间 module/namespace
namespace Module1 {
  export interface SubModule1 {}
  
  export interface SubModule2 {}
}
const module: Module1.SubModule = {}

  1. 声明文件 declare

declare 定义的类型只会用于编译时的检查,编译结果中会被删除。

在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。

假如我们想使用第三方库,比如 jQuery,我们通常这样获取一个 id 是 foo 的元素:

$('#foo');
// 或
jQuery('#foo');

但是在 TypeScript 中,我们并不知道 $ 或 jQuery 是什么东西:

jQuery('#foo');

// index.ts(1,1): error TS2304: Cannot find name 'jQuery'.

这时,我们需要使用 declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对:

declare var jQuery: (selector: string) => any;

jQuery('#foo');

declare 定义的类型只会用于编译时的检查,编译结果中会被删除。

上例的编译结果是:

jQuery('#foo');

声明文件
声明文件以 .d.ts 为后缀,例如:

runoob.d.ts
声明文件或模块的语法格式如下:

declare module Module_Name {
}
TypeScript 引入声明文件语法格式:

/// <reference path = " runoob.d.ts" />

  1. 泛型
function makeState<S>() {
  let state: S
  function getState() {
    return state
  }
  function setState(x: S) {
    state = x
  }
  return { getState, setState }
}


// 限制它就只能输入输出number和string类型
function makeState<S extends number | string>() {
  let state: S
  function getState() {
    return state
  }
  function setState(x: S) {
    state = x
  }
  return { getState, setState }
}
// 如果我传入boolean类型
const boolState = makeState<boolean>()

// 泛型的默认类型
function makeState<S extends number | string = number>()



// https://segmentfault.com/a/1190000021219586

泛型其实可以当作普通函数在声明时的一个参数,这个参数代表类型。
我们可以给函数值参数设置默认值,
也可以通过typescipt的泛型给函数类型参数设置默认值。

function regularFunc(x = 2)
regularFunc()
function genericFunc<T = number>()
genericFunc()

其实上面已经涉及到泛型约束了,我们再来看一下更具体的泛型约束

//泛型无法知道具体的类型,所以无法操作它的属性和方法
function Test<T> (a:T):void {
  console.log(a.length);  // error
}
Test<string>('1')

interface hasLengthProp {
    length : number;
}
function Test<T extends hasLengthProp>(a:T):void {
    console.log(a.length);
}
  1. 别名
type strAria = string; // 给 string 类型定义了 strAria别名
const str: strAria = 'abc';

type fnAria = () => string;
function (callback:fnAria):void {
    callback();
}

// 我们使用 type 定了一个字符串字面量类型 EventNames,它只能取三种字符串中的一种
type EventName = 'xm' | 'xh' | 'xb';
const str : EventName = 'xb'
const elseStr : EventName = 'xf' // error, 不在这几个名字当中

  1. 声明合并

就是说声明两个同样的接口、类或者函数,会进行合并操作。

合并的属性的类型必须是唯一的

interface Alarm {
    price: number;
     alert(s: string): string;
}
interface Alarm {
    weight: number;
    alert(s: string, n: number): string;
}
//===> 相当于
interface Alarm {
    price: number;
    weight: number;
    alert(s: string, n: number): string;
}

demo

我们可以先做一个简单的 demo 来感受一下 TypeScript 的魅力。首先在 src/page 新建一个 Demo.tsx.
在其中定义一个无状态组件 Hello。

import React from 'react';

const Hello = ({ name }) => <div>Hello,{name}</div>;

接下来我们使用它,

const App = () => <Hello />;

export default App;

我们发现他抛出了如下错误 :

不能将类型“{}”分配给类型“{ name: any; }”。类型“{}”中缺少属性“name”。

因为我们使用了 name,Typescript 认为他是必填参数。如果不存在便认为程序错误,并造成编译失败。这可以帮助我们避免很多低级错误。

我们也可以使用 Class 语法来声明组件,代码如下:

class Message extends React.Component<{
  message: string;
}> {
  public render() {
    return <div>{this.props.message}</div>;
  }
}

我们可以通过 <> 的第一个参数来指定 props 的类型。通过第二个参数来指定 state 的类型
代码如下:

class Message extends React.Component<
  {
    message: string;
  },
  {
    count: number;
  }
> {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  public render() {
    return (
      <div>
        {this.props.message}
        {this.state.count}
      </div>
    );
  }
}

在这里,我们定义了一个 包含 count 的 state ,count 的类型为 number。然后在类 constructor 内部初始化 state。其余使用方式与 javascript 中相同。

我们可以自行修改 count,

public increment = () => {
  const { count } = this.state;
  this.setState({
    count: count + 1
  });
};

interface IProps {
  aProps: string;
  bProps: string;
}
interface IState {
  aState: string;
  bState: string;
}

class App extends React.PureComponent<IProps, IState> {
  state = {
    aState: '',
    bState: '',
  };
}

TS 对 类装饰器的静态解析还不支持, 建议React 和 Redux 的绑定函数 connect 用函数写法

const mapStateToProps = (state: {}, ownProps: IProps) => {};
const mapDispatchToProps = {};

export default connect(mapStateToProps, mapDispatchToProps)(App);

以上是自己的一点点对typescript的基础知识的了解,当然以上肯定会存在很多不足的地方,我会继续更加深入的学习,欢迎各位提出宝贵的意见或建议,也希望能帮助到你从中获得一些知识!

认真学前端 QQ群:619069335

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 如果说这世界上你只剩下做一件事的时间了,你会选择做什么呢?这貌似很不好回答,但是就现在的我能做的那就是每天...
    睡不醒的懒虫阅读 147评论 0 0
  • 17.唠叨男 我觉得史上最唠叨的男人就是唐僧了:“哦,你想要啊?你想要啊,你想要说清楚就行了嘛。你想要的话我会给你...
    刘秀玲阅读 1,961评论 37 29
  • 远看山峦叠嶂, 近瞧郁郁葱葱, 师友相约游蓟州, 住在望松。 林间花红柳绿, 山坡果树相嵌, 踏着薄雾等高处, 浮...
    9610ab214539阅读 567评论 0 1
  • **Splendid** Adj. a splendid opportunity. **Aware** Adj. ...
    seedcm阅读 233评论 0 0