u.id = 2; // ^-- Cannot assign to 'id' because it is a read-only property.ts u.scores = [100, 65] // ^-- Cannot assign to 'scores' because it is a read-only property.ts
但是并没有对 scores 内部的属性做只读约束(只读约束只在第一层)
1 2
u.scores[0] = 100; // 不报错
深入函数语法
对象的语法全都适用于函数
1 2 3 4 5 6 7
type F = { (a: number, b: number): number; readonly count?: number[]; };
constfn: F = (x, y) => x + y; fn.count[0] = 1;
声明函数的四种方式
先写类型再赋值
1 2
typeF1 = (a: number, b: number) =>number; constf1: F1 = (a, b) => a + b;
箭头函数
1 2 3 4
const f2 = (a: number, b: number): number => { return a + b; }; typeF2 = typeof f2;
普通函数
1 2 3 4
functionf3(this: unknown, a: number, b: number): number { return a + b; } typeF3 = typeof f3;
匿名普通函数
1 2 3 4
const f4 = function (this: unknown, a: number, b: number): number { return a + b; }; typeF4 = typeof f4;
之前在联合类型中讲过,可以使用类型谓词 is 来收窄类型,当时只简单提了一下不推荐使用箭头函数,这里说一下为什么
1 2 3 4 5 6 7 8 9 10 11 12
typePerson = { name: string } typeAnimal = {}
functionisPerson(x: Person | Animal): x is Person { return'name'in x }
functionfn(a: Person | Animal) { if (isPerson(a)) { a // Person } }
可以使用箭头函数实现 isPerson
1
const isPerson = (x: Person | Animal): x is Person => 'name'in x
但需要注意的是,如果使用的是箭头函数,不能先写类型再赋值
1 2 3
type A = (x: Person | Animal) => x is Person constisPerson: A = x =>'name'in x // ^--- Type '(x: Person | Animal) => boolean' is not assignable to type 'A'
在右边加上 x is Person 就不报错了
1 2
type A = (x: Person | Animal) => x is Person constisPerson: A = (x): x is Person => 'name'in x