function test<T>(v: T) {
console.log(v);
}
test<boolean>(true);
test("hello");
test(123);
泛型与强类型相关,即需要进行严格的类型检查,又想少写相似代码,所以干脆用某个符号来代替类型。泛型这个名称本身可能并不是很好理解,但是如果借用 C++ 的“模板”概念,就好理解了。比如上面的泛型函数,根据后面的调用,可以被解释为三个函数,相当于套用模板,用实际类型代替了 T
:
function test(v: boolean) { ... }
function test(v: string) { ... }
function test(v: number) { ... }
关于泛型,更详细的内容可以参考 Handbook 的 Generic 部分。
类型就简述到这里,简单的类型一看就能明白,高级一点的类型我们以后再开专题来详述。不过既然选择使用 TypeScript,必然会用到它的静态类型特性,那就必须强化识别类型的意识,并养成这样的习惯。对于纯 JSer 来说,这是一个巨大的挑战。
声明类型
声明类型,主要是指声明变量/常量,函数/方法和类成员的类型。JS 中使用 var 声明一个变量,ES6 扩展了 let 和 const。这几种声明 TypeScript 都支持。要为变量或者常量指定类型也很简单,就是在变量/常量名后面加个冒号,再指定类型即可,比如
function pow(n: number): number {
return n * n;
}
function test(): void {
for (let i: number = 0; i < 10; i++) {
console.log(pow(i));
}
}
这段代码演示了对函数类型、参数类型和变量类型地声明。这相对于 JavaScript 代码来说,似乎变得更复杂了。但是考虑下,如果我们在某处不小心这样调用了 pow
:
let n = "a";
let r = pow(n);
JavaScript 不会提前检查错误的,只有在执行到 r = pow(n)
的时候给 r
赋值为 NaN
。然后如果别处又用到 r
,可能就会造成连锁错误,可能很要调试一阵才把问题找得出来。
不过上面两行代码在 TypeScript 里是通不过转译的,它会报告一个类型不匹配的错误:
argument of type 'string' is not assignable to parameter of type 'number'.
声明类成员
这时先来看一段 JavaScript 代码
class Person {
constructor(name) {
this._name = name;
}
get name() {
return this._name;
}
}
这段 JavaScript 代码如果翻译成 TypeScript 代码,会是这样
class Person {
PRivate _name: string;
public constructor(name: string) {
this._name = name;
}
public get name(): string {
return this._name;
}
}
注意到 private _name: string
,这句话是在声明类成员变量 _name
。JavaScript 里是不需要声明的,对 this._name
赋值,它自然就有了,但在 TypeScript 里如果不声明,就会报告属性不存在的错误:
Property '_name' does not exist on type 'Person'.
虽然写起来麻烦了一点,但是我也能理解 TypeScript 的苦衷。如果没有这些声明,tsc 就搞不清楚你在使用 obj.xxxx
或者 this.xxxx
的时候,这个 xxxx
到底确实是你想要添加的属性名称呢,还是你不小心写错了的呢?
另外要注意到的是 private
和 public
修饰符。JavaScript 中存在私有成员,为了实现私有,大家都想了不少办法,比如闭包。
TypeScript 提供了 private
来修饰私有成员,protected
修改保护(子类可用)成员,public
修饰公共成员。如果不添加修饰符,默认作为 public
,以兼容 JavaScript 的类成员定义。不过特别需要注意的是,这些修饰符只在 TypeScript 环境(比如转译过程)有效,转译成 JavaScript 之后,仍然所有成员都是公共访问权限的。比如上例中的 TypeScript 代码转译出来基本上就是之前的 JavaScript 代码,其 _name
属性在外部仍可访问。
当然在 TypeScript 代码中,如果外部访问了 _name
,tsc 是会报告错误的
Property '_name' is private and only accessible within class 'Person'.
所以应用内使用 private
完全没问题,但是如果你写的东西需要做为第三方库发布,那就要想一些手段来进行“私有化”了,其手段和 JavaScript 并没什么不同。
小结
从 JavaScript 语法改写 TypeScript 语法,我们来做个简单的总结:
类成员需要声明。
变量、函数参数和返回值需要申明类型。
如果所有这些东西都要声明类型,工作量还是满大的,所以我建议:就接口部分声明类型。也就是说,类成员、函数/方法的参数和返回类型要声明类型,便于编辑器进行语法提示,局部使用的变量或者箭头函数,在能明确推导出其类型的时候,可以不声明类型。
扩展阅读
关注作者的公众号“边城客栈” →
脚本宝典总结
以上是脚本宝典为你收集整理的从 JavaScript 到 TypeScript - 声明类型全部内容,希望文章能够帮你解决从 JavaScript 到 TypeScript - 声明类型所遇到的问题。
如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。