对于一个工作代码库,TS 有不同严格等级的类型系统。
- 仅仅基于 JS 代码的类型推断
- 在 JS 中使用 JSDoc 来逐步增加类型
- 在 JS 文件中使用
// @ts-check
- 使用 TS 代码
-
对 JS 文件使用 TS 编译器
TS 编译器也可以处理纯 JS 文件:
使用 —allowJs 选项,TS 编译器可以将输入文件夹中的 JS 文件复制到输出文件夹。优点:当把 JS 代码迁移到 TS 代码的时候,可以混合使用两种代码文件,逐步完成迁移
- 使用 —checkJs 选项,编译器会逐步对 JS 文件进行类型检查。可以使用
// @ts-check
和// @ts-nocheck
对不同的代码块进行针对性的设置 - 使用
JSDoc
进行类型注释 - 使用
--noEmit
参数,编译器只对文件进行类型检查,而不输出任何文件对 JS 文件使用类型检查
@type
```typescript /* @type {HTMLElement} / const myElement = document.querySelector(selector); element.dataset.myData = “”;
/* @type {(string | boolean)} / const stringOrBoolean = true
/**
- A map-like object that maps arbitrary
string
properties tonumber
s. * - @type {Object.
} */ var stringToNumber; ``` 可以对变量设置固定的类型,或者设置联合类型。联合类型中的括号是可选的。 @param 和 @returns
```typescript // Parameters may be declared in a variety of syntactic forms /** - @param {string} p1 - A string param.
- @param {string=} p2 - An optional param (Closure syntax)
- @param {string} [p3] - Another optional param (JSDoc syntax).
- @param {string} [p4=”test”] - An optional param with a default value
- @return {string} This is the result
*/
function stringsStringStrings(p1, p2, p3, p4) {
// TODO
}
```
@template
使用@template
来声明泛型函数 ```typescript /** - @template T
- @param {T} x - A generic parameter that flows through to the return type
- @return {T} */ function id(x) { return x; }
const a = id(“string”); const b = id(123); const c = id({});
<a name="AsG8J"></a>
### @enum
使用 `@enum` 来模拟枚举类型
```typescript
/** @enum {number} */
const JSDocState = {
BeginningOfLine: 0,
SawAsterisk: 1,
SavingComments: 2,
};
JSDocState.SawAsterisk;
JS Class extensions
用来模拟 @public
, @private
, @protected
// @ts-check
class Car {
constructor() {
/** @private */
this.identifier = 100;
}
printIdentifier() {
console.log(this.identifier);
}
}
const c = new Car();
函数参数是默认可选的
/**
* @param {string} [somebody] - Somebody's name.
*/
function sayHello(somebody) {
if (!somebody) {
somebody = "John Doe";
}
console.log("Hello " + somebody);
}
sayHello();
使用 var-args 参数声明来对 arguments 的使用来进行推断
/** @param {...number} args */
function sum(/* numbers */) {
var total = 0;
for (var i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
在 extends clause
使用 @augments
来显式指定类型
import { Component } from "react";
/**
* @augments {Component<{a: number}, State>}
*/
class MyComponent extends Component {
render() {
this.props.b; // Error: b does not exist on {a:number}
}
}
未设定的参数默认为 any
/** @type{Array} */
var x = [];
x.push(1); // OK
x.push("string"); // OK, x is of type Array<any>
/** @type{Array.<number>} */
var y = [];
y.push(1); // OK
y.push("string"); // Error, string is not assignable to number