掬月在手 發表於 2020-3-25 11:03:00

typescript 文档

<h1 id="typescript-要点知识整理">TypeScript 要点知识整理</h1>
<p>本篇主要是整理一下 typescript 相关的知识点。</p>
<h2 id="什么是-typescript">什么是 TypeScript</h2>
<blockquote>
<p>TypeScript 是 JavaScript 的一个超集,主要提供了<strong>类型系统</strong>和对 <strong>ES6</strong> 的支持。</p>
</blockquote>
<h2 id="安装-typescript-及编译-ts-文件">安装 TypeScript 及编译 Ts 文件</h2>
<pre><code class="language-ts">npm -g install typescrip // 全局安装 typescript
</code></pre>
<p>全局安装 typescript 后即可在终端使用 <strong>tsc</strong> 命令了,编译 ts 文件命令如下:</p>
<pre><code class="language-ts">// hello.ts
function foo(name: string) {
console.log(`Hello ${name}`);
}
foo('Cooper') // Hello Cooper

// terminal
tsc hello.ts // 编译 ts 文件后生成对应的 hello.js 文件
</code></pre>
<h2 id="typescript-的类型检查说明">TypeScript 的类型检查说明</h2>
<p>Ts 只会进行静态类型检查,如果发现错误,编译的时候就会报错。日常一般搭配 Eslint 或 Tslint 使用,在编码过程中即会报出对应错误。</p>
<h2 id="基本数据类型">基本数据类型</h2>
<p>通过在变量后加 <strong>:类型</strong> 声明变量的类型。</p>
<h3 id="1-bolean-布尔值">1. bolean 布尔值</h3>
<pre><code class="language-ts">let isSuccess: boolean = true; // 正确
let isSuccess: boolean = new Boolean(1); // 错误,new 产生的是一个Boolean类型的对象,类型为 Boolean,是一个构造函数,不同于基本数据类型 boolean
let isSuccess: Boolean = new Boolean(1); // 正确
let isSuccess: boolean = Bealean(1); // 返回的仍是一个基本boolean类型的值
</code></pre>
<p><strong>说明: 在 typescript 中,boolean 是基本数据类型,而 Boolean 是一个构造函数,定义为 boolean 的值不能是 Boolean 对象。其他基本数据类型亦如此</strong></p>
<h3 id="2-数字">2. 数字</h3>
<pre><code class="language-ts">let num: number = 3; // 正确
num = "3"; // 报错,申明了变量为 number 类型,怎么能赋 string 类型的值呀!
</code></pre>
<h3 id="3-字符串">3. 字符串</h3>
<pre><code class="language-ts">let name: string = "Cooper";
let templetStr: string = `Hello, ${name}`; // es6 模版字符串
</code></pre>
<h3 id="4-空值">4. 空值</h3>
<p>JavaScript 中没有空值(Void)的概念,在 TypeScript 中空值一般用来表示一个函数没有返回值</p>
<pre><code class="language-ts">// 定义一个没有返回值的返回的函数
function foo(name: string): void {
console.log(name);
}
</code></pre>
<h3 id="5-null-和-undefined">5. Null 和 Undefined</h3>
<p>定义为 null 类型的变量只能被赋值为 null, 定义为 undefined 的变量只能被赋值为 undefined</p>
<pre><code class="language-ts">let u: undefined = undefined;
let m: null = null;
</code></pre>
<h2 id="任意值">任意值</h2>
<p>定义为任意值的变量可以被赋值为任意类型。在任意类型的变量上访问任意属性和方法都是可以的。声明一个变量为 any 类型后,对其进行任意操作返回的都是 any 类型。未声明类型的变量默认为 any 类型。</p>
<pre><code class="language-ts">let anyValue: any = "123";
anyValue = 1; // 不会报错,因为 anyValue 的类型为任意值
</code></pre>
<p><strong>注意:any 用起来虽然特别方便,但是建议日常开发能不用就不用,毕竟 TypeScript 是为了更规范的书写 Js 代码,如果全部都定义成 any 类型,那就失去了 TypeScript 的意义。</strong></p>
<h2 id="类型推论">类型推论</h2>
<p>如果没有明确的指明某个变量的类型, 那么 TypeScript 会依照类型推论的规则推导出一个类型。</p>
<pre><code class="language-ts">let str = "Cooper";
str = 7; // 报错,根据类型推论确认 str 为 string 类型,则不可以赋 string 外的值
</code></pre>
<h2 id="联合属性">联合属性</h2>
<p>联合类型表示取值可以为多种类型中的一种,各个类型间使用分隔线 <strong>|</strong> 连接</p>
<pre><code class="language-ts">let strOrNumValue: string | number = "test";
</code></pre>
<ul>
<li>访问联合类型的属性和方法 当一个变量定义为联合类型,我们只能访问联合类型的公共方法和属性</li>
</ul>
<pre><code class="language-ts">function getLength(something: string | number) {
return something.length; // 报错,number 类型不包含 length 属性
}
function myToString(something: string | number) {
return something.toString(); // 正确,number 和 string 类型都包含 toString 方法
}
</code></pre>
<ul>
<li>联合类型的变量在被赋值后,会根据类型推论的规则推导出一个类型</li>
</ul>
<pre><code class="language-ts">let something: string | number;
something = "Cooper";
console.log(something.length); // 5, something 赋值字符串后,被推导为 string 类型,因而可以访问 length 属性
something = 3;
console.log(something.length); // 报错
</code></pre>
<h2 id="对象的类型---接口">对象的类型 - 接口</h2>
<p>在 TypeScript 中,我们用接口来定义对象的类型,接口命名,一般以大写字母 <strong>I</strong> 开头,且 I 后面的首个字母一并大写,了解 Java 的同学应该很熟悉,这与 Java 是一致的。</p>
<pre><code class="language-ts">interface IPerson {
name: string;
age: number;
}
// 接口的所有属性都需要包含,且各个属性类型一致,否则报错
let Cooper: IPerson = {
name: "Cooper",
age: 23,
};
</code></pre>
<ul>
<li>可选属性<br>
用来表示某个对象中的属性是可选的。</li>
</ul>
<pre><code class="language-ts">interface IPerson {
name: string;
age?: number; // 我们在属性后使用 ? 后表示该属性为可选属性
}
// 可只包含 name 属性,age 为可选属性,可不定义,但是不能添加接口未定义属性
let Cooper: IPerson = {
name: "Cooper",
};
</code></pre>
<ul>
<li>任意属性</li>
</ul>
<pre><code class="language-ts">interface IPerson {
name: string;
age?: string;
: string;
}
let cooper: IPerson = {
// true
name: "Cooper",
gender: "male", // 添加的任意属性 gender
};
</code></pre>
<p><strong>注意:一旦定义了任意类型,那么确认属性和可选的属性的类型必须是任意属性类型的子类</strong>,举个例子,以上定义改为</p>
<pre><code class="language-ts">// 报错,任意属性为 string,不包括可选属性的 number 类型
interface IPerson {
name: string;
age?: number;
: string;
}
// 应改为以下形式
interface IPerson {
name: string;
age?: number;
: string | number; // 上面定义的具体类型也应包含在任意类型
}
</code></pre>
<ul>
<li>只读属性 有时候我们希望有些属性只能在初始化时被赋值,后续不允许修改,则可以使用 <strong>readonly</strong> 关键字来定义</li>
</ul>
<pre><code class="language-ts">interface IPerson {
readonly id: number;
name: string;
}
let cooper: IPerson = {
id: 14202119,
name: "Cooper",
};
cooper.id = 14020120; // 报错,只读属性不允许再次修改值
</code></pre>
<h2 id="数组的类型定义">数组的类型定义</h2>
<p>在 TypeScript 中数组可以使用多种方式定义类型。</p>
<ul>
<li>类型 + 中括号</li>
</ul>
<pre><code class="language-ts">let list: number[] = ; // 数组中的每一项都 number 类型
</code></pre>
<ul>
<li>数组泛型,Array, T 为泛型</li>
</ul>
<pre><code class="language-ts">let list: Array&lt;number&gt; = ;
</code></pre>
<ul>
<li>用接口表示</li>
</ul>
<pre><code class="language-ts">// key 为 number 类型,即数组下标,值为 number 类型,即 value
interface INumberArray {
: number;
}
let list: INumberArray = ;
</code></pre>
<ul>
<li>对象数组的定义</li>
</ul>
<pre><code class="language-ts">interface IItem = {
    name: string,
    age: number
}
// 数组中是一个对象,且对象中属性需和定义的一致
let list: IItem[] = [
    {
      name: 'Cooper',
      age: 23
    },
    {
      name: 'Bob',
      age: 23
    },
]
</code></pre>
<h2 id="函数类型">函数类型</h2>
<ul>
<li>函数的声明方式</li>
</ul>
<pre><code class="language-ts">// 函数式声明
function foo(name) {
console.log(name);
}
// 函数表达式
const mySun = function (x, y) {
return x + y;
};
</code></pre>
<ul>
<li>函数式声明定义类型</li>
</ul>
<pre><code class="language-ts">// 接收两个 number 的参数,不允许少传或多传参数,且函数的返回值必须为 number 类型
function(x: number, y: number): number {
return x + y;
}
</code></pre>
<ul>
<li>函数表达式定义类型</li>
</ul>
<pre><code class="language-ts">let myFun: (x: number, y: number) =&gt; number = function (
x: number,
y: number
): number {
return x + y;
};
// 左侧变量的类型可省略,等号左边会根据类型推论推断出来,即:
let myfun = function (x: number, y: number): number {
return x + y;
};
</code></pre>
<ul>
<li>使用接口定义</li>
</ul>
<pre><code class="language-ts">interface IMyFun {
(x: number, y: number): boolean;
}
let myFun: IMyFun = function (x: number, y: number): boolean {
return false;
};
</code></pre>
<ul>
<li>可选参数和剩余参数</li>
</ul>
<pre><code class="language-ts">// y 为可选参数
function myFun(x: number, y?: number): number {
if (y) {
    return x + y;
}
}
// 剩余参数
function myFun(x: number, ...ars: any[]) {
console.log(args);
}
myFun(1, 2, "3"); //
</code></pre>
<h2 id="类型断言">类型断言</h2>
<p>类型断言即手动(或者说是强制?。?)指定一个变量的类型</p>
<ul>
<li>
<p>语法</p>
<p>&lt;类型&gt;变量</p>
<p>变量 as 类型 // tsx 中仅支持此种方式</p>
</li>
</ul>
<pre><code class="language-ts">function myFun(x: number | string) {
console.log(&lt;string&gt;x.length); // 此处变量 x 的属性为 string | number,想直接使用 length 属性,则需要通过类型断言指定 x 的属性为 string
}
</code></pre>
<ul>
<li>
<p>特殊</p>
<p>当我们声明可选参数时,我们需要先判断参数存在才能使用</p>
</li>
</ul>
<pre><code class="language-ts">function myFun(x: number, y?: number): number {
if (y) {
    const result = x + y; // 不进行判断将会报错
    return result;
}
}
// 也可通过断言
function myFun(x: number, y?: number): number {
const result = x + !y; // !表示改变量一定存在
return result;
}
</code></pre>
<p>注意:类型断言不是类型转换,断言一个联合类型中不存在的类型将会报错。</p>
<h2 id="声明文件">声明文件</h2>
<p>当我们直接在项目中引入第三方的模块,并且使用其方法或者是属性,ts 是不会报错的,因为这些类型和方法都是没有进行声明的。因为我们需要使用声明文件来定义这些属性和方法的类型。对于一些常用的第三方模块, typescript 社区已经帮我们定义好了,只要我们在使用 npm 安装模块的时候,在模块名前带上 <strong>@type/</strong></p>
<pre><code class="language-ts">npm install express --save// 安装普通的 express 模块
npm install @/types/express --save-dev// 安装带有声明文件的 express 模块,只有本地开发环境才进行安装
</code></pre>
<p>对于一些不常用的第三方模块,在 typescript 社区中无法安装带有声明文件的模块,我们可以在项目的根目录下创建一个 index.d.ts 文件,在其中对其进行声明,防止 ts 报错。</p>
<pre><code class="language-ts">declare module "so-utils"; // 声明 so-utils 为一个模块,防止 import * from 'so-utils' 报错
</code></pre>
<p>以上可防止模块引入时报错,但对于模块定义的属性和方法依旧没有提示,想要完整的代码提示功能则要定义完整的声明文件,关于声明文件的书写名,参见TypeScript 入门教程 - 声明文件</p>
<h2 id="内置对象">内置对象</h2>
<p>JavaScript 中有很多定义好的对象,我们可以当作定义好的类型来使用。</p>
<pre><code class="language-ts">let bodyDoc: HTMLDocument = document.body; // html文档流
</code></pre>
<h2 id="类型别名">类型别名</h2>
<p>我们使用 type 关键字来声明类型的别名</p>
<pre><code class="language-ts">type Name = string;
type NameResolver = () =&gt; string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
    return n;
} else {
    return n();
}
}
</code></pre>
<h2 id="字符串字面量类型">字符串字面量类型</h2>
<p>字符串字面量类型用来约束取值只能是某几个字符串取值中一个</p>
<pre><code class="language-ts">type eventName = "click" | "scroll" | "mousemove";
// 第二个参数 event 只能是'click' |'scroll' | 'mousemove'三个中的某一个
function handleEvent(ele: Element, event: EventNames) {
// do something
}
handleEvent(doument.getELementById("hello"), "scroll"); // true
handleEvent(doument.getELementById("hello"), "dbclick"); // 报错
</code></pre>
<h2 id="参考">参考</h2>
<ul>
<li>TypeScript 入门教程</li>
</ul><br><br>
来源:https://www.cnblogs.com/frank-link/p/12564658.html
頁: [1]
查看完整版本: typescript 文档