TypeScript数据类型:
string:字符串
number:数字
boolean:true/false
string[]:数组
any:可以是任何类型。当你不希望某个特定的值导致类型检查错误时,你可以使用它。
以下都不会报编译异常
let value: any;
value.foo.bar; // OK
value.trim(); // OK
value(); // OK
new value(); // OK
value[0][1]; // OK
unknown:未知类型。任意类型都可以赋值给unknow类型。但unknown类型只能赋值给unknown和any类型。
let value: unknown;
value.foo.bar; // Error
value.trim(); // Error
value(); // Error
new value(); // Error
value[0][1]; // Error
let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
let value5: string = value; // Error
let value6: object = value; // Error
let value7: any[] = value; // Error
let value8: Function = value; // Error
类型注释用法,不加类型注解,会自动推断。
变量型注解:let myName: string = "Alice";
参数类型注解:
function greet(name: string) {
console.log("Hello, " + name.toUpperCase() + "!!");
}
返回类型注解:
function getFavoriteNumber(): number {
return 26;
}
返回 Promise 的函数:
async function getFavoriteNumber(): Promise<number> {
return 26;
}
匿名函数
const names = ["Alice", "Bob", "Eve"];
// Contextual typing for function - parameter s inferred to have type string
names.forEach(function (s) {
console.log(s.toUpperCase());
});
// Contextual typing also applies to arrow functions
names.forEach((s) => {
console.log(s.toUpperCase());
});
对象类型
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 });
可选属性
function printName(obj: { first: string; last?: string }) {
// ...
//使用last属性时必须检查非空
if (obj.last !== undefined) {
// OK
console.log(obj.last.toUpperCase());
}
//或者
console.log(obj.last?.toUpperCase());
}
// Both OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });
联合类型,可选任意一种传递。
function printId(id: number | string | string[]) {
if (typeof id === "string") {
// In this branch, id is of type 'string'
console.log(id.toUpperCase());
} else if(Array.isArray(id)){
console.log("Hello, " + x.join(" and "));
}else {
// Here, id is of type 'number'
console.log(id);
}
}
类型别名
type anyType = number | string;
type Point = {
x: number;
y: number;
};
function printCoord(pt: Point) {
console.log(pt.x + "/" + pt.y);
}
接口
interface Point {
x: number;
y: number;
}
function printCoord(pt: Point) {
console.log(pt.x + "/" + pt.y);
}
printCoord({ x: 100, y: 100 });
类型别名和接口的区别
类型别名和接口非常相似,在很多情况下你可以在它们之间自由选择。 interface 的几乎所有功能都在 type 中可用,主要区别在于无法重新打开类型以添加新属性,而接口始终可扩展。
扩展接口
interface Animal {
name: string;
}
interface Bear extends Animal {
honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;
通过交集扩展类型
type Animal = {
name: string;
}
type Bear = Animal & {
honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;
向现有接口添加新字段
interface Window {
title: string;
}
interface Window {
ts: TypeScriptAPI;
}
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
类型创建后无法更改
type Window = {
title: string;
}
type Window = {
ts: TypeScriptAPI;
}
// Error: Duplicate identifier 'Window'.
类型断言
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
字面类型
let x: "hello" = "hello";
只接受一组已知值的函数
function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}
数字字面类型的工作方式相同
function compare(a: string, b: string): -1 | 0 | 1 {
return a === b ? 0 : a > b ? 1 : -1;
}
bigint
// Creating a bigint via the BigInt function
const oneHundred: bigint = BigInt(100);
// Creating a BigInt via the literal syntax
const anotherHundred: bigint = 100n;
symbol
JavaScript 中有一个原语用于通过函数 Symbol() 创建全局唯一引用:
const firstName = Symbol("name");
const secondName = Symbol("name");
if (firstName === secondName) {
This comparison appears to be unintentional because the types 'typeof firstName' and 'typeof secondName' have no overlap.
// Can't ever happen
}