本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2020-11-27
# 安装
npm install -g typescript
# 生成tsconfig.json 可设置指定编译之后的js存放目录 outDir
tsc --init
# 编译
tsc index.ts
# 监视并实时编译 vscode -> 菜单栏-终端 -> 运行任务 -> tsc:监视 - tsconfig.json
var x: any = {};
if (typeof x === 'string') {
console.log(x.splice(3, 1));
// 错误,'string'上不存在'splice'方法
}
x.foo(); // 合法
TypeScript会读懂在条件语句中使用的typeof
的用法,会自动推断出x
一定是string
类型。
使用一个变量强制描述为指定形式的函数。
var greet:(name: string) => string = function (name: string): string {
return "Hi!" + name;
}
// 这在使用回调函数时十分有用 指定回调函数的形式
function sum(a: number, b: number, callback:(result: number) => void) {
callback(a + b);
}
模块导入
可能会看到一些类似Cannot find name 'require'.
和Cannot find name 'define'.
的错误。 遇到这种情况说明你在使用模块。
// For Node/CommonJS
declare function require(path: string): any;
// For RequireJS/AMD:
declare function define(...args: any[]): any;
// 具体表现
var foo = require("foo");
foo.doStuff();
define(["foo"], function(foo) {
foo.doStuff();
})
// 转换为TypeScript
import foo = require("foo");
foo.doStuff();
模块导出
// 1.普通导出成
module.exports.feedPets = function(pets) {
// ...
}
// 转换为ts
export function feedPets(pets) {
// ...
}
// 2.重写导出对象的方式导出
function foo() {
// ...
}
module.exports = foo;
// 转换为ts
function foo() {
// ...
}
export = foo;
连续添加属性
var options = {};
options.color = "red";
options.volume = 11;
// 转换为
interface Options { color: string; volume: number }
let options = {} as Options;
options.color = "red";
options.volume = 11;
// 或者直接
let options = {
color: "red",
volume: 11
};
你可能会试图使用Object
或{}
来表示一个值可以具有任意属性,因为Object
是最通用的类型。然而在这种情况下any
是真正想要使用的类型,因为它是最灵活的类型。记住,当你使用any
时,你会失去大多数TypeScript提供的错误检查和编译器支持。
当任何值可能为null
,你可以使用联合类型。比如,某值可能为number
或null
,你可以声明它的类型为number | null
。
假设有一个值TypeScript认为可以为null
或undefined
,但是你更清楚它的类型,你可以使用!
后缀。
declare var foo: string[] | null;
foo.length; // error - 'foo' is possibly 'null'
foo!.length; // okay - 'foo!' 仅仅只有当foo是 string[] 时才会访问它的length属性
通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。它没有运行时的影响,只是在编译阶段起作用。
let someValue: any = "this is a string";
// 确认someValue就是一个string 并访问了length属性
let strLength: number = (<string>someValue).length;
或者,
let strLength: number = (someValue as string).length;
当引入第三方库的时候,可以这么使用断言。
import { Selector } from 'testcafe';
interface CoustomSelector extends Selector {
myCustomMethod: () => void;
}
// Selctor 函数返回的也是一个Selector类型
var a = Selector('#btn');
a.myCustomMethod(); // Error
var b = <CoustomSelector>Selector('#btn');
b.myCustomMethod();
// ,这里就会被断言为 CoustomSelector
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
let a: number[] = [1, 2, 3, 4];
// 创建只读的数组 并且要求项都是number类型 将所有可变方法都去掉了
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error! 把整个ReadonlyArray 赋值到一个普通数组也是不被允许
// 但是可以使用类型断言重写
a = ro as number[];
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig):void {
console.log(config);
}
// error, color拼写错误 对象文字只能指定已知的属性,但“colour”不存在类型“SquareConfig”中
let mySquare = createSquare({ colour: "red", width: 100 });
// 使用断言 表示我确定它属于SquareConfig类型,只是没传可选参数color
let mySquare = createSquare({ colour: "red", width: 100 } as SquareConfig);
// 或者 面临另外一种场景 SquareConfig不仅带有上面定义的类型的color和width属性,并且还会带有任意数量的其它属性。
// 可以这么定义接口
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
// 这样即使拼写错误 也会被当做是额外的属性 不会报错
let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);
比较两个函数
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;
y = x; // OK
x = y; // Error
要查看x是否能赋值给y,首先看它们的参数列表。 x的每个参数必须能在y里找到对应类型的参数。 注意的是参数的名字相同与否无所谓,只看它们的类型。 这里,x的每个参数在y中都能找到对应的参数,所以允许赋值。
第二个赋值错误,因为y有个必需的第二个参数,但是x并没有,所以不允许赋值。
等式右边的函数参数必须能在等式左边的函数参数列表中找到对应类型的参数,
let x = () => ({name: 'Alice'});
let y = () => ({name: 'Alice', location: 'Seattle'});
x = y; // OK
y = x; // Error because x() lacks a location property
类型系统强制源函数的返回值类型必须是目标函数返回值类型的子类型。
等式右边的返回值对象必须拥有左边返回值对象的所有属性。