参考:
对象类型
除了基元之外,你最常遇到的类型是对象类型。这指的是任何带有属性的JavaScript值,这几乎是所有的对象 为了定义一个对象类型,我们简单地列出它的属性和它们的类型。
例如,这里有一个函数,它接收一个点状对象。
// The parameter's type annotation is an object type
function printCoord(pt: { x: number; y: number }) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });
在这里,我们给参数注解了一个有两个属性的类型—x和y—它们都是数字类型。你可以用,或;来分隔这些属性,最后一个分隔符是可选的,无论如何。
每个属性的类型部分也是可选的。如果你没有指定一个类型,它将被假定为任何类型。
联合类型
TypeScript 的类型系统允许你使用大量的操作符从现有的类型中建立新的类型。现在我们知道如何编写一些类型,是时候开始以有趣的方式组合它们了。
定义一个联合类型
你可能看到的第一个组合类型的方法是联合类型。联合类型是一个由两个或多个其他类型组成的类型,代表可能是这些类型中任何一个的值。我们把这些类型中的每一个称为联盟的成员。
让我们写一个可以对字符串或数字进行操作的函数。
function printId(id: number | string) {
console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// Error
printId({ myID: 22342 });
Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
类型别名 Type Aliases
我们一直在使用对象类型和联合类型,把它们直接写在类型注解中。这是很方便的,但是我们经常想多次使用同一个类型,并且用一个名字来指代它。
一个类型别名正是如此—任何类型的名称。类型别名的语法是
type Point = {
x: number;
y: number;
};
// Exactly the same as the earlier example
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
比如常见的react props的类型定义
实际上,你可以使用一个类型别名来给任何类型命名,而不仅仅是一个对象类型。例如,一个类型别名可以命名一个联合类型。
type ID = number | string;
接口
接口声明是命名一个对象类型的另一种方式。
interface Point {
x: number;
y: number;
}
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
别名vs接口
类型别名和接口非常相似,而且在很多情况下,你可以在它们之间自由选择。几乎所有接口的功能都可以在类型别名中使用,关键的区别在于,类型别名不能被重新打开以添加新的属性,而接口总是可以被扩展。
比如
类型断言 Type Assertions
有时,你会拥有TypeScript无法知道的关于值的类型的信息。
例如,如果你使用 document.getElementById,TypeScript 只知道这将返回某种 HTMLElement,但你可能知道你的页面将总是有一个具有给定 ID 的 HTMLCanvasElement。
在这种情况下,你可以使用一个类型断言来指定一个更具体的类型。
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
像类型注解一样,类型断言会被编译器删除,不会影响你的代码的运行行为。
你也可以使用角括号语法(除非代码是在.tsx文件中,可能被识别为react组件标签),这是等同的。
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
提醒您。因为类型断言是在编译时删除的,所以没有与类型断言相关的运行时检查。如果类型断言是错误的,就不会有异常或空值产生。
TypeScript只允许类型断言转换为一个类型的更具体或更不具体的版本。这条规则防止了 “不可能 “的胁迫,比如。
const x = “hello” as number; Conversion of type ‘string’ to type ‘number’ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown’ first.
有时这条规则可能过于保守,会不允许可能有效的更复杂的胁迫。如果发生这种情况,你可以使用两个断言,首先是对任意(或未知),然后是对所需类型。
const a = (expr as any) as T