为了使程序有用,我们需要能够处理一些最简单的數據单元:数字、字符串、结构、布尔值等等。在 TypeScript 中,我们支持与您在 JavaScript 中期望的相同类型,并添加了一个额外的枚举类型来帮助您。
布尔值
最基本的数据类型是简单的真/假值,JavaScript 和 TypeScript 称之为boolean
值。
tsTry
letisDone : boolean = false;
数字
与 JavaScript 一样,TypeScript 中的所有数字都是浮点数或大整数。这些浮点数的类型为number
,而大整数的类型为bigint
。除了十六进制和十进制字面量之外,TypeScript 还支持 ECMAScript 2015 中引入的二进制和八进制字面量。
tsTry
letdecimal : number = 6;lethex : number = 0xf00d;letbinary : number = 0b1010;letoctal : number = 0o744;letbig : bigint = 100n;
字符串
在 JavaScript 中,无论是网页还是服务器,创建程序的另一个基本部分是处理文本数据。与其他语言一样,我们使用类型string
来表示这些文本数据类型。与 JavaScript 一样,TypeScript 也使用双引号 ("
) 或单引号 ('
) 来包围字符串数据。
tsTry
letcolor : string = "blue";color = 'red';
您还可以使用模板字符串,它可以跨越多行并包含嵌入表达式。这些字符串用反引号 (`
) 字符包围,嵌入表达式采用${ expr }
的形式。
tsTry
letfullName : string = `Bob Bobbington`;letage : number = 37;letsentence : string = `Hello, my name is ${fullName }.I'll be ${age + 1} years old next month.`;
这等效于像这样声明sentence
tsTry
letsentence : string ="Hello, my name is " +fullName +".\n\n" +"I'll be " +(age + 1) +" years old next month.";
数组
TypeScript 与 JavaScript 一样,允许您使用值数组。数组类型可以用两种方式之一编写。在第一种方式中,您使用元素的类型后跟[]
来表示该元素类型的数组
tsTry
letlist : number[] = [1, 2, 3];
第二种方式使用泛型数组类型Array<elemType>
tsTry
letlist :Array <number> = [1, 2, 3];
元组
元组类型允许您表达一个具有固定数量元素的数组,这些元素的类型是已知的,但不必相同。例如,您可能希望将一个值表示为一个string
和一个number
对
tsTry
// Declare a tuple typeletx : [string, number];// Initialize itx = ["hello", 10]; // OK// Initialize it incorrectlyType 'number' is not assignable to type 'string'.x = [10 ,"hello" ]; // Error
Type 'string' is not assignable to type 'number'.2322
2322Type 'number' is not assignable to type 'string'.
Type 'string' is not assignable to type 'number'.
当使用已知索引访问元素时,将检索正确的类型
tsTry
// OKconsole .log (x [0].substring (1));Property 'substring' does not exist on type 'number'.2339Property 'substring' does not exist on type 'number'.console .log (x [1].(1)); substring
访问已知索引集之外的元素会导致错误
tsTry
Tuple type '[string, number]' of length '2' has no element at index '3'.2493Tuple type '[string, number]' of length '2' has no element at index '3'.x [3 ] = "world";Object is possibly 'undefined'.console .log (x [5 ].toString ());
Tuple type '[string, number]' of length '2' has no element at index '5'.2532
2493Object is possibly 'undefined'.
Tuple type '[string, number]' of length '2' has no element at index '5'.
枚举
对来自 JavaScript 的标准数据类型集的一个有益补充是enum
。与 C# 等语言一样,枚举是一种为一组数值提供更友好名称的方法。
tsTry
enumColor {Red ,Green ,Blue ,}letc :Color =Color .Green ;
默认情况下,枚举从0
开始对成员进行编号。您可以通过手动设置其成员之一的值来更改此设置。例如,我们可以将前面的示例从0
开始改为1
tsTry
enumColor {Red = 1,Green ,Blue ,}letc :Color =Color .Green ;
或者,甚至可以手动设置枚举中的所有值
tsTry
enumColor {Red = 1,Green = 2,Blue = 4,}letc :Color =Color .Green ;
枚举的一个方便功能是,您也可以从数值转到枚举中该值的名称。例如,如果我们有值2
,但不知道它映射到上面的Color
枚举中的什么,我们可以查找相应的名称
tsTry
enumColor {Red = 1,Green ,Blue ,}letcolorName : string =Color [2];// Displays 'Green'console .log (colorName );
未知
在编写应用程序时,我们可能需要描述我们不知道类型的变量。这些值可能来自动态内容(例如,来自用户),或者我们可能希望在我们的 API 中有意接受所有值。在这些情况下,我们希望提供一个类型,告诉编译器和未来的读者这个变量可以是任何东西,所以我们给它unknown
类型。
tsTry
letnotSure : unknown = 4;notSure = "maybe a string instead";// OK, definitely a booleannotSure = false;
如果您有一个类型未知的变量,可以通过执行 `typeof` 检查、比较检查或更高级的类型保护来将其缩小到更具体的类型,这些类型保护将在后面的章节中讨论。
tsTry
declare constmaybe : unknown;// 'maybe' could be a string, object, boolean, undefined, or other typesconstType 'unknown' is not assignable to type 'number'.2322Type 'unknown' is not assignable to type 'number'.: number = aNumber maybe ;if (maybe === true) {// TypeScript knows that maybe is a boolean nowconstaBoolean : boolean =maybe ;// So, it cannot be a stringconstType 'boolean' is not assignable to type 'string'.2322Type 'boolean' is not assignable to type 'string'.: string = aString maybe ;}if (typeofmaybe === "string") {// TypeScript knows that maybe is a stringconstaString : string =maybe ;// So, it cannot be a booleanconstType 'string' is not assignable to type 'boolean'.2322Type 'string' is not assignable to type 'boolean'.: boolean = aBoolean maybe ;}
Any
在某些情况下,并非所有类型信息都可用,或者其声明将需要不适当的努力。这些情况可能发生在来自没有使用 TypeScript 或第三方库的代码的值上。在这些情况下,我们可能希望选择退出类型检查。为此,我们将这些值标记为 `any` 类型。
tsTry
declare functiongetValue (key : string): any;// OK, return value of 'getValue' is not checkedconststr : string =getValue ("myString");
`any` 类型是处理现有 JavaScript 的一种强大方法,允许您在编译期间逐步选择加入和选择退出类型检查。
与 `unknown` 不同,`any` 类型的变量允许您访问任意属性,即使是那些不存在的属性。这些属性包括函数,TypeScript 不会检查它们的存在或类型。
tsTry
letlooselyTyped : any = 4;// OK, ifItExists might exist at runtimelooselyTyped .ifItExists ();// OK, toFixed exists (but the compiler doesn't check)looselyTyped .toFixed ();letstrictlyTyped : unknown = 4;'strictlyTyped' is of type 'unknown'.18046'strictlyTyped' is of type 'unknown'.. strictlyTyped toFixed ();
`any` 将继续通过您的对象传播。
tsTry
letlooselyTyped : any = {};letd =looselyTyped .a .b .c .d ;
毕竟,请记住,`any` 的所有便利都以失去类型安全为代价。类型安全是使用 TypeScript 的主要动机之一,您应该尽量避免在不需要的情况下使用 `any`。
Void
`void` 有点像 `any` 的反面:完全没有类型。您通常会看到它作为不返回值的函数的返回类型。
tsTry
functionwarnUser (): void {console .log ("This is my warning message");}
声明 `void` 类型的变量没有用,因为您只能将 `null`(仅当未指定 `strictNullChecks` 时,请参见下一节)或 `undefined` 分配给它们。
tsTry
letunusable : void =undefined ;// OK if `--strictNullChecks` is not givenunusable = null;
Null 和 Undefined
在 TypeScript 中,`undefined` 和 `null` 实际上都有它们各自的类型,分别命名为 `undefined` 和 `null`。与 `void` 类似,它们本身并不十分有用。
tsTry
// Not much else we can assign to these variables!letu : undefined =undefined ;letn : null = null;
默认情况下,null
和 undefined
是所有其他类型的子类型。这意味着您可以将 null
和 undefined
分配给类似 number
的类型。
但是,当使用 strictNullChecks
标志时,null
和 undefined
只能分配给 unknown
、any
及其各自的类型(唯一的例外是 undefined
也可以分配给 void
)。这有助于避免许多常见的错误。在您想要传入 string
或 null
或 undefined
的情况下,可以使用联合类型 string | null | undefined
。
联合类型是一个高级主题,我们将在后面的章节中介绍。
注意:我们鼓励尽可能使用
strictNullChecks
,但为了本手册的目的,我们将假设它已关闭。
从不
never
类型表示永远不会出现的类型的值。例如,never
是函数表达式或箭头函数表达式的返回类型,该表达式始终抛出异常或永远不返回。当变量被任何永远不会为真的类型守卫缩小时,它们也会获得 never
类型。
never
类型是所有类型的子类型,可以分配给所有类型;但是,没有类型是 never
的子类型,也不能分配给 never
(除了 never
本身)。即使 any
也不能分配给 never
。
一些返回 never
的函数示例
tsTry
// Function returning never must not have a reachable end pointfunctionerror (message : string): never {throw newError (message );}// Inferred return type is neverfunctionfail () {returnerror ("Something failed");}// Function returning never must not have a reachable end pointfunctioninfiniteLoop (): never {while (true) {}}
对象
object
是一种表示非原始类型的类型,即任何不是 number
、string
、boolean
、bigint
、symbol
、null
或 undefined
的类型。
使用 object
类型,可以更好地表示 Object.create
等 API。例如
tsTry
declare functioncreate (o : object | null): void;// OKcreate ({prop : 0 });create (null);Argument of type 'undefined' is not assignable to parameter of type 'object | null'.2345Argument of type 'undefined' is not assignable to parameter of type 'object | null'.create (); // with `--strictNullChecks` flag enabled, undefined is not a subtype of null undefined Argument of type 'number' is not assignable to parameter of type 'object'.2345Argument of type 'number' is not assignable to parameter of type 'object'.create (42 );Argument of type 'string' is not assignable to parameter of type 'object'.2345Argument of type 'string' is not assignable to parameter of type 'object'.create ("string" );Argument of type 'boolean' is not assignable to parameter of type 'object'.2345Argument of type 'boolean' is not assignable to parameter of type 'object'.create (false );
通常,您不需要使用它。
类型断言
有时你会遇到这样一种情况,你比 TypeScript 更了解一个值。通常,当你知道某个实体的类型比其当前类型更具体时,就会发生这种情况。
类型断言是一种告诉编译器“相信我,我知道自己在做什么”的方式。类型断言就像其他语言中的类型转换,但它不执行任何特殊的检查或数据重构。它对运行时没有影响,纯粹由编译器使用。TypeScript 假设你,程序员,已经执行了任何你需要的特殊检查。
类型断言有两种形式。
一种是as
语法
tsTry
letsomeValue : unknown = "this is a string";letstrLength : number = (someValue as string).length ;
另一种是“尖括号”语法
tsTry
letsomeValue : unknown = "this is a string";letstrLength : number = (<string>someValue ).length ;
这两个示例是等效的。使用哪一个主要取决于个人喜好;但是,当使用带有 JSX 的 TypeScript 时,只允许使用as
样式的断言。
关于let
的说明
你可能已经注意到,到目前为止,我们一直在使用let
关键字,而不是你可能更熟悉的 JavaScript 的var
关键字。let
关键字实际上是 TypeScript 提供的较新的 JavaScript 结构。你可以在手册参考中阅读关于变量声明,了解let
和const
如何解决var
的许多问题。
关于Number
、String
、Boolean
、Symbol
和Object
你可能会误以为类型 `Number`、`String`、`Boolean`、`Symbol` 或 `Object` 与上面推荐的小写版本相同。然而,这些类型并不指代语言原语,几乎不应该用作类型。
tsTry
functionreverse (s :String ):String {returns .split ("").reverse ().join ("");}reverse ("hello world");
相反,请使用类型 `number`、`string`、`boolean`、`object` 和 `symbol`。
tsTry
functionreverse (s : string): string {returns .split ("").reverse ().join ("");}reverse ("hello world");