TypeScript 1.8
Type 参数作为约束
使用 TypeScript 1.8,可以使用类型参数约束从相同的类型参数列表中引用类型参数。以前这是一个错误。这种能力通常被称为 F-Bounded Polymorphism 。
示例
function assign<T extends U, U>(target: T, source: U): T {
for (let id in source) {
target[id] = source[id];
return target;
let x = { a: 1, b: 2, c: 3, d: 4 };
assign(x, { b: 10, d: 20 });
assign(x, { e: 0 }); // Error
控制流量分析错误
TypeScript 1.8 引入了控制流分析来帮助捕捉用户倾向于遇到的常见错误。请阅读以获取更多详细信息,并查看这些错误的实际操作:

无法访问的代码
保证不会在运行时执行的语句现在可以正确标记为不可达代码错误。例如,下面的语句无条件的
return
,
throw
,
break
或
continue
语句被认为是不可到达的。使用
--allowUnreachableCode
禁用可达代码检测和报告。
示例
以下是一个无法访问的代码错误的简单示例:
function f(x) {
if (x) {
return true;
else {
return false;
x = 0; // Error: Unreachable code detected.
}
此功能捕获的更常见的错误是在
return
语句后添加换行符:
function f() {
return // Automatic Semicolon Insertion triggered at newline
x: "string" // Error: Unreachable code detected.
}
由于 JavaScript 在行尾自动终止
return
语句,因此对象字面量变为块。
未使用的标签
未使用的标签也被标记。就像无法访问的代码检查一样,这些默认情况下都会打开; 用于
--allowUnusedLabels
停止报告这些错误。
示例
loop: while (x > 0) { // Error: Unused label.
}
隐式返回
具有不返回 JS 值的代码路径的函数隐式返回
undefined
。这些现在可以被编译器标记为隐式返回。该检查默认
关闭
; 使用
--noImplicitReturns
打开它。
示例
function f(x) { // Error: Not all code paths return a value.
if (x) {
return false;
// implicitly returns `undefined`
}
案例条款落后
在 case 子句非空的 switch 语句中,TypeScript 可以报告错误情况。该检查默认
关闭
,可以使用启用
--noFallthroughCasesInSwitch
。
示例
有了
--noFallthroughCasesInSwitch
这个例子会触发一个错误:
switch (x % 2) {
case 0: // Error: Fallthrough case in switch.
console.log("even");
case 1:
console.log("odd");
break;
}
但是,在下面的示例中,由于落空情况为空,因此不会报告错误:
switch (x % 3) {
case 0:
case 1:
console.log("Acceptable");
break;
case 2:
console.log("This is *two much*!");
break;
}
React 中的无状态函数组件
TypeScript 现在支持 无状态函数组件 。这些是轻松构成其他组件的轻量级组件:
// Use parameter destructuring and defaults for easy definition of 'props' type
const Greeter = ({name = 'world'}) => <div>Hello, {name}!</div>;
// Properties get validated
let example = <Greeter name='TypeScript 1.8' />;
对于这个功能和简化的道具,一定要使用 react.d.ts 的最新版本 。
React中简化的
props
类型管理
在带有最新版本 react.d.ts 的 TypeScript 1.8 中(见上),我们也大大简化了
props
类型的声明。
特别:
-
您不再需要显式声明
ref
和key
或extend React.Props
-
ref
和key
性能会出现正确的类型上的所有组件
-
该
ref
属性在无状态函数组件的实例中被正确禁止
从模块中增加全局/模块范围
用户现在可以声明他们想要创建的任何扩展,或者任何其他使用者已经创建的扩展到现有模块。模块增强看起来像普通的旧环境模块声明(即
declare module "foo" { }
语法),并且直接嵌套在您自己的模块中,或者直接嵌套在另一个顶级环境外部模块中。
此外,TypeScript 还具有表单
全局
增强的概念
declare global { }
。这允许模块增加全局类型(
Array
如有必要)。
模块扩充的名称使用与模块说明符相同的一组规则
import
和
export
声明来解决。模块扩充中的声明以与在同一文件中声明的方式相同的方式与任何现有声明合并。
模块增强和全局增强都不能将新项添加到顶层作用域 - 它们只能“修补”现有的声明。
示例
这里
map.ts
可以声明它将在内部修补
Observable
类型
observable.ts
并将
map
方法添加到它。
// observable.ts
export class Observable<T> {
// ...
}
// map.ts
import { Observable } from "./observable";
// Create an augmentation for "./observable"
declare module "./observable" {
// Augment the 'Observable' class definition with interface merging
interface Observable<T> {
map<U>(proj: (el: T) => U): Observable<U>;
Observable.prototype.map = /*...*/;
// consumer.ts
import { Observable } from "./observable";
import "./map";
let o: Observable<number>;
o.map(x => x.toFixed());
同样,全局范围可以通过使用
declare global
声明的模块进行扩充:
示例
// Ensure this is treated as a module.
export {};
declare global {
interface Array<T> {
mapToNumbers(): number[];
Array.prototype.mapToNumbers = function () { /* ... */ }
字符串文字类型
API 对于某些值期望一组特定的字符串并不罕见。例如,考虑一个 UI 库,它可以在控制 动画的“缓动”的 同时在屏幕上移动元素 。
declare class UIElement {
animate(options: AnimationOptions): void;
interface AnimationOptions {
deltaX: number;
deltaY: number;
easing: string; // Can be "ease-in", "ease-out", "ease-in-out"
}
但是,这很容易出错 - 没有任何东西阻止用户意外地拼错其中一个有效缓动值: