一、编译选项
- outDir: 编译输出目录
- target: 指定编译的代码版本目标 默认ES3
- watch: 监听模式,只要文件变更,会自动编译
// 命令行模式`getComputeStyle`
tsc --outDir ./dist --target es6 ./src/helloTypescript.ts
tsc -p ./config/xxx.json // -p可以指定配置文件目录
{
"compilerOptions": {
/* Basic Options */
"watch":true,
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "umd", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["DOM","ESNext","DOM.Iterable"], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. default:false */
// "checkJs": true, /* Report errors in .js files. default:false */
// "jsx": "preserve", /* 在 `.tsx`文件里支持JSX Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* 生成d.ts文件 Generates corresponding '.d.ts' file. 不能和allowjs同时为true*/
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* 连接并输出到单一个文件中 Concatenate and emit output to single file. 只有module为'amd', 'system'才适用*/
"outDir": "./dist", /*输出文件目录 Redirect output structure to the directory. */
// "rootDir": "./", /* 输入文件的根目录 Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* 将每个文件作为单独的模块(与“ts.transpileModule”类似)Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"baseUrl": "./", /* 解析非绝对模块的基础目录 Base directory to resolve non-absolute module names. */
"paths": {
// * 类似于alias
"*":["node_modules/@types","src/typings"]
}, /* 模块名到基于 `baseUrl`的路径映射的列表 A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"rootDirs": [
// 表示这两个目录中的文件放到同一个目录中
"src/module",
"src/core"
], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* 要包含的类型声明文件路径列表。List of folders to include type definitions from. */
// "types": [], /* 要包含的类型声明文件名列表。 Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"files":[],// 要编译的文件路径(不是目录) 优先级 files => include => 根目录 不能用*通配符
"include": ["./src/**/*"], // 要编译的文件目录或文件
"exclude": [], // 编译排除的文件目录或文件
"extends": "" // 基础其它文件,会覆盖
}
二、类型系统
1、基础类型
let title: string = "标题";
let n: number = 100;
let isOk: boolean = true;
2、空和未定义类型 Null和undefined
let un: undefined;
un = 1; // error 只能是undefined
let o: null;
o = 1; // error 只能是null
null和undefined是所有类型的子类型
let a: string = '哈哈';
a = null; // 可以
a = undefined; // 可以
未赋值情况下,值为undefined
同时未声明类型 则是any类型
let b;
strictNullCheck 会检测null ele是any或者null
let ele = document.querySelector('#box');
const id = ele.id // error ele可能是null
3、object
let obj: object = {
x: 1,
y: 2
}
// object只是告诉obj是一个对象 有.toString等方法,但是没有说明有x属性
obj.x = 3; // error
// 内置对象类型
let d1: Date = new Date();
let st = new Set([1, 2]);
// 包装器类型
// 包装器类型不能赋值给基础类型
let str1 = new String('abc');
str1 = 'def'; // ok
let str2 = 'abc';
str2 = new String('def'); // error
4、数组类型
// 数组类型
let arr1: string[] = [];
arr1.push(1); // error
arr1.push('a'); // ok
// 用泛型表示数组
let arr2: Array<number> = [];
// 元组类型 数组可以存储不同类型数值
// 个数和类型位置都要对应
let arr3: [number, string] = [10, 10]; // error
let arr4: [number, string] = [10, 'aaaa']; // ok
5、枚举类型
// key不能是数值,value可以是数字或字符串,默认是0 1 2 。。。。
enum HTTP_CODE {
OK = 200,
NOT_FOUND = 404
}
console.log(HTTP_CODE[200]) // "OK"
// 书写语义化
if (Response.code === HTTP_CODE.OK) {
}
// 接口
enum URLS {
USER_LOGIN = '/user/login',
USER_REGISTER = '/user/register'
}
6、void、never
// 无值类型
function fn(): void {
return 1; // error
}
// never 没有正常执行下去
function fn2(): never {
throw new Error()
}
let nv = fn2(); // ok nv类型是never
let ay: any = 1;
nv = ay; // error
6、any和unknown
// any类型 不知道数据类型时使用 any就是绕过所有检测
let ay1: any;
ay1 = 1;
ay1 = 'aa'; // ok
let ay2: any = 11;
ay2 = 'aa'; // ok
ay2.a.b.c = 5; // ok
// unknown 安全的any类型
let a1: any;
a1.b.c = 1; // ok
let a2: unknown;
a2.b.c = 2; // error 不会无脑的忽略错误
7、函数类型
let add = function (x: number, b: number): number {
return x + b;
}
function foreach(data: string[], callback: (a: number, b: string) => void) {
for (let i = 0; i < data.length; i++) {
callback(i, data[i])
}
}
let arr5 = ['a', 'b', 'c'];
foreach(arr5, function () {
})
8、接口interface
interface Point {
x: number,
y: number,
z?: number, // 可选属性,表示 number|undefined error 可能是undefined 因为有任意属性,这里就没必要了
readonly id: number, // 只读属性
[props: string]: number // 任意属性 方便扩展 x y z也必须是字符串
}
let p: Point;
p = {
x: 1,
y: 1,
id: 234567,
k: 67890
};
p[1] = 555 // 1也会被转成字符串
p.id = 56789; // error 只读属性,不能修改
接口索引只能是字符串和数字
interface Point2 {
[props: string]: number,
[props: number]: number,
}
let p2: Point2 = {};
p2[1] = 1;
p2['a'] = 2;
当同时存在数字和字符串类型索引时 ,数字类型的值必须是字符串类型值得子类型
interface Point3 {
[props: string]: number,
[props: number]: string, // error
}
interface Point4 {
[props: string]: Object,
[props: number]: string, // ok
}
接口用在函数中
interface Addfun {
(x: number, y: string): number;
}
type Addfun2 = (x: number, y: string) => number;
const addx: Addfun = (x, y) => {
return 5
}
interface Counter {
(): void;
counter: number;
}
const getCounter = (): Counter => {
const c = () => { c.counter++ }
c.counter = 0;
return c;
}
9、联合类型
function css(ele: Element, attr: string, value: string | number) {}
let box = document.querySelector('.box');
if (box) {
css(box, 'width', '100px');
css(box, 'opacity', 1);
}
10、交叉类型
interface o1 {
x: number;
y: number;
}
interface o2 {
z: number;
}
let obj11: o1 = {
x: 1,
y: 2
}
let obj22: o2 = {
z: 3
}
let obj33: o1 & o2 = {
x: 1,
y: 2,
z: 3
}
11、字面量类型
function setPosition(ele: Element, direction: 'left' | 'top') {}
let box1 = document.querySelector('.box');
if (box1) {
setPosition(box1, 'top')
}
12、类型别名
type dir = 'left' | 'top';
type o3 = o1 & o2;
13、类型推导
let x; // any
x = 1;
x = 'a';
14、类型断言
let ele1 = <HTMLImageElement>document.getElementById('my'); // Element
let ele2 = document.getElementById('my') as HTMLImageElement; // Element
console.log(ele1.src)
15、类型操作符
let colors = {
color1: 'red',
color2: 'blue'
}
let typeColors = typeof colors; // "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
type b = typeof colors; // {color1:string,color2:string}
let data: b = {
color1: 'a',
color2: 'a'
}
16、keyof操作的是类型
interface Person {
name: string;
age: number;
}
type ab = keyof Person; // 'name' | 'age'
let data2: ab = 'name'
let p1 = {
name: 'haixing',
age: 35
}
function getPersonVal(k: keyof typeof p1) {
return p1[k]
}
function css2(ele: Element, attr: keyof CSSStyleDeclaration) {
return getComputedStyle(ele)[attr]
}
let box3 = document.querySelector('.box');
if (box3) {
css2(box3, 'abc')
}
17、in操作符
let ax = 'a' in { a: 3 }
type abc = 'name' | 'age';
type newPerson = { // 添加到新类型
[k in abc]: string
}
let np:newPerson={name:'a',age:`12`};
18、继承
interface type1 {
x: number;
y: string;
}
interface type2 extends type1 {
z: boolean;
}
let ex1: type2 = { x: 1, y: 'a', z: true };
ex1.x = 5;
19、泛型
interface type1 {
x: number;
y: string;
}
// T指定了传参 像Array<string>
function fn4<T extends type1>(args: T) { }
fn4({ x: 1, y: 'a' })
fn4({ x: 1, y: 'a', z: '哈哈' })
fn4({ x: 1, k: 'a' }) // error
20、类型保护
function toUpperCase(arg: string | string[]) {
console.log(arg.length); // ok
console.log(arg.toUpperCase()); // error
}
断言
if (!!(<string>arg).toUpperCase) {
return (<string>arg).toUpperCase()
} else {
(<string[]>arg).push('aaa')
}
typeof也会作为类型检查的依据
if (typeof arg === 'string') {
return arg.toUpperCase()
} else {
arg.push('aaa')
}
instanceof
if (arg instanceof Array) {
arg.push('aaa')
} else {
return arg.toUpperCase()
}
自定义类型保护 关键 xx is type
// 返回这个会被作为类型推断依据
function canEach(data: Element[] | NodeList | Element): data is Element[] | NodeList {
return (<NodeList>data).forEach !== undefined
}
function fn5(elements: Element[] | NodeList | Element) {
if (canEach(elements)) {
elements.forEach(() => { })
} else {
elements.classList.add('box')
}
}
let eles = document.querySelectorAll('.box');
fn5(eles);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。