JavaScript手册2——TypeScipt

TypeScript是JavaScript的超集,为JavaScript 添加了可选的类型、类和模块系统。它可以编译成普通的JavaScript代码。 TypeScript支持任意浏览器,任意环境,任意系统并且是开源的。

TypeScript

BASIC TYPES

1
2
> let n: number = 2
statically declare n as a number with the value 2.

OPERATORS

1
2
> 4 / '2'
type error: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

JAVASCRIPT BUILTINS

1
2
> const n: number = (123).toString()
type error: Type 'string' is not assignable to type 'number'.

INFERENCE

1
2
3
> let n = 2 + 2
let s: string = n
type error: Type 'number' is not assignable to type 'string'.

FUNCTIONS

1
2
3
4
5
6
7
8
> function numToString(x: number): string {
return x.toString()
}
Declare numToString as a function taking a number and returning a string.
> function double(x: number): string {
return 2 * x
}
type error: Type 'number' is not assignable to type 'string'.

ARRAYS

1
2
3
> let strings: string[] = ['a', 2]
strings
type error: Type 'number' is not assignable to type 'string'.

TYPE KEYWORD

1
2
3
4
> type MyStringType = string
let s: MyStringType = 'hello'
s
'hello'

SYNTAX ERRORS VS TYPE ERRORS

1
2
> 1 &+@ 2
syntax error: Expression expected.

OBJECT TYPES

1
2
3
4
5
6
> type User = {
email: string,
}
let amir: User = {email: 'amir@example.com'}
amir.email
'amir@example.com'

RETURN TYPE INFERENCE

1
2
3
4
5
> function two() {
return 1 + 1
}
let s: string = two()
type error: Type 'number' is not assignable to type 'string'.

TYPE UNIONS

1
2
3
4
5
> function isNumber(arg: number | string): boolean {
return typeof arg === 'number'
}
[isNumber(1), isNumber('a')]
[true, false]

LITERAL TYPES

1
2
3
4
5
6
> let one: 1 = 1
one
1
> let one: 1 = 2
one
type error: Type '2' is not assignable to type '1'.

CONDITIONAL NARROWING

1
2
3
4
5
6
7
> function add1IfNumber(n: number | boolean) {
// Without narrowing, "n + 1" would be a type error because we can't
// add booleans.
return (typeof n === 'number') ? n + 1 : n
}
[add1IfNumber(1), add1IfNumber(true)]
[2, true]

TUPLES

1
2
3
4
5
6
> let numberAndString: [number, string] = [1, 'a']
numberAndString[1]
'a'
> let numberAndString: [number, string] = [1, 2]
numberAndString[1]
type error: Type 'number' is not assignable to type 'string'.

LITERAL OBJECT TYPES

1
2
3
4
5
> function extractEmail(hasEmail: {email: string}): string {
return hasEmail.email
}
extractEmail({email: 'amir@example.com'})
'amir@example.com'

GENERIC ARRAYS

1
2
3
4
> let numbers: number[] = [1]
let numbers2: Array<number> = numbers
numbers2
[1]

OBJECT NARROWING

1
2
3
> type HasName = {name: string}
let amir: HasName = {name: 'Amir', admin: true}
The extra "admin" property is discarded.

NULLABILITY

1
2
3
4
> let numberMaybe: number | undefined
numberMaybe can be either a number or undefined.
> let numberMaybe: number | null
numberMaybe can be either a number or null.

GENERIC FUNCTIONS

1
2
3
4
5
> function first<T>(elements: Array<T>): T {
return elements[0]
}
first<boolean>([true, false])
true

FUNCTION TYPES

1
2
3
4
5
6
> function add1(n: number): number {
return n + 1
}
const myAdd1: (n: number) => number = add1
myAdd1(3)
4

ANY

1
2
3
4
> const n: any = 5
const s: string = n
s
5

DISCRIMINATED UNIONS

1
2
3
4
5
6
7
8
9
> type StartedCourse = {
started: true,
lastInteractionTime: Date,
}
type UnstartedCourse = {
started: false,
}
type Course = StartedCourse | UnstartedCourse
Variables of type Course must match either the StartedCourse type or the UnstartedCourse type.

LOGICAL OPERATOR NARROWING

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> function arrayLength(strings: string[] | undefined): number | undefined {
return strings && strings.length
}
[arrayLength(['a', 'b']), arrayLength(undefined)]
[2, undefined]
> function numberOrOne(n: number | undefined): number {
return n || 1
}
[numberOrOne(3), numberOrOne(undefined)]
[3, 1]
> function lengthOrNumber(n: number | number[]): number {
return Array.isArray(n) ? n.length : n
}
[lengthOrNumber([1, 2]), lengthOrNumber(5)]
[2, 5]

TYPE INTERSECTIONS

1
2
3
4
> type HasEmail = {email: string}
type CanBeAdmin = {admin: boolean}
type User = HasEmail & CanBeAdmin
A User has both an email property and an admin property.

FUNCTIONS AS ARGUMENTS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> type TakesNumberReturnsNumber = (x: number) => number
function add1(x: number): number {
return x + 1
}
const arrayOfFunctions: TakesNumberReturnsNumber[] = [add1]
const aFunction: TakesNumberReturnsNumber = arrayOfFunctions[0]
aFunction(2)
3
> function callFunction(f: () => number) {
return f()
}
callFunction(
() => 3
)
3

ERROR HANDLING WITH UNIONS

1
2
3
4
5
6
7
8
9
10
11
> type ConversionSucceeded = {
kind: 'success',
value: number,
}
type ConversionFailed = {
kind: 'failure',
reason: string,
}
type ConversionResult = ConversionSucceeded | ConversionFailed
function safeNumber(s: string): ConversionResult { ... }
Force callers to handle failures.

UNKNOWN

1
2
3
4
5
6
7
8
> const n: unknown = 5
const n2: number = n
n2
type error: Type 'unknown' is not assignable to type 'number'.
> const n: unknown = 5
const n2: number = typeof n === 'number' ? n : 0
n2
5

VOID

1
2
3
4
> function f() {
}
const n: number = f()
type error: Type 'void' is not assignable to type 'number'.

UNDEFINED IN ARRAYS

1
2
3
> let strings: string[] = []
strings[1]
undefined

GENERIC OBJECT TYPES

1
2
3
4
5
6
7
8
9
10
> type Pants<T1, T2> = {
left: T1,
right: T2,
}
let myPants: Pants<string, number> = {
left: 'phone',
right: 5,
}
myPants.left
'phone'

GENERIC FUNCTION TYPES

1
2
3
4
5
6
7
> function first<T>(elements: Array<T>): T {
return elements[0]
}
type First<T> = (elements: Array<T>) => T
const firstString: First<string> = first
firstString(['a', 'b', 'c'])
'a'

TYPE PREDICATES

1
2
3
4
5
6
7
> function isString(s: unknown): s is string {
return typeof s === 'string'
}
const s: unknown = 'a string'
const s2: string = isString(s) ? s : ''
s2
'a string'

INDEX SIGNATURES

1
2
3
4
5
6
7
8
9
10
> const strings: {[index: number]: string} = ['a', 'b', 'c']
strings
['a', 'b', 'c']
> type LoginCounts = {[userName: string]: number}
const loginCounts: LoginCounts = {
Amir: 5,
Betty: 7,
}
loginCounts.Betty
7

GENERIC FUNCTION INFERENCE

1
2
3
4
5
> function length<T>(elements: T[]): number {
return elements.length
}
length([1, 2])
2

SHARED FIELDS

1
2
3
4
> type HasEmail = {email: string}
type User = HasEmail & {admin: boolean}
type Company = HasEmail & {accountNumber: number}
Users and Companies both have an email property.

OPTIONAL CHAINING

1
2
3
4
5
6
7
8
9
10
11
12
> type User = {name: string}
function getUser(): User | undefined {
return {name: 'Amir'}
}
getUser()?.name
'Amir'
> type User = {name: string}
function getUser(): User | undefined {
return undefined
}
getUser()?.name
undefined

NULLISH COALESCING

1
2
3
4
5
6
> null ?? 1
1
> undefined ?? 1
1
> false ?? 1
false

ASSERTION FUNCTIONS

1
2
3
4
5
6
7
8
9
10
> function assert(condition: boolean): asserts condition {
if (!condition) {
throw new Error('Assertion failed')
}
}
const var1: number | string = ((): number | string => 1)()
assert(typeof var1 === 'number')
const var2: number = var1
var2
1

NEVER

1
2
3
4
5
> function throws(): never {
throw new Error('oh no')
}
throws()
Error: oh no

RECURSIVE TYPES

1
2
3
4
> type NestedNumberArray = number | NestedNumberArray[]
const n: NestedNumberArray = [[[[1]], 2, [3]]]
n
[[[[1]], 2, [3]]]

Regex

LITERALS

1
2
> /a/
(matches 'a')

WILDCARD

1
2
> /./
(matches anything)

BOUNDARIES

1
2
3
4
> /^/
(matches start of string)
> /$/
(matches end of string)

REPETITION

1
2
3
4
> /a+/
(matches one or more 'a')
> /a*/
(matches zero or more 'a')

OR

1
2
> /a|b/
(matches 'a' or 'b')

PARENS

1
2
> /^(a|b)+$/
(matches a, b, ab, ba, ...)

ESCAPING

1
2
3
4
> /\+/
(matches '+')
> /\$/
(matches '$')

BASIC CHARACTER SETS

1
2
3
4
> /[ab]/
(matches 'a' or 'b')
> /[a-z]/
(matches lowercase letters)

BASIC CHARACTER CLASSES

1
2
3
4
5
6
> /\s/
(matches whitespace)
> /\d/
(matches digits)
> /\D/
(matches not-digits)

CHARACTER CLASSES

1
2
> /\w/
(matches identifiers)

CHARACTER SETS

1
2
3
4
> /[$]/
(matches '$')
> /[a^]/
(matches 'a' and '^')

MAYBE

1
2
> /a?/
(matches 'a' or '')

CONSTRAINED REPETITION

1
2
3
4
5
6
> /a{3}/
(matches exactly three "a"s)
> /a{3,5}/
(matches between 3 and 5 "a"s)
> /a{3,}/
(matches at least 3 "a"s)

WORD BOUNDARIES

1
2
> /\b/
(matches word boundary)

HEX CODES

1
2
> /\xhh/
(matches hex codes)

CHARACTER CLASSES IN SETS

1
2
> /[\s-]/
(matches whitespace or '-')

 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×