TypeScript 常见问题
奴止
Oct 25, 2022
Last edited: 2022-10-25
type
Post
status
Published
date
Oct 25, 2022
slug
typescript-fqa
summary
一些常见的 TypeScript 问题,方便你我他。
tags
TypeScript
前端开发
category
技术随手记
icon
password
Property
Oct 25, 2022 03:50 PM
持续更新中….
本文中的代码可以复制粘贴到 TypeScript Playground 中自行体会。
几个关键点
- TypeScript是结构化类型(结构相同那就是一样的类型)
- 子类型可以赋值给父类型(
animal = dog
),反之不可
- 属性多的是子类型,但是联合类型越多反而是父类型
- 用是否安全来考虑类型是否兼容的问题
协变、逆变(啥玩意儿?)
忘记那些名词,以类型安全来考虑就行。
简单类型
- 简单类型1
type Parent = { name: string } type Child = { name: string age: number } let p: Parent = { name: 'parent' } let c: Child = { name: 'child', age: 1 } p = c // ok c = p // error: Property 'age' is missing in type 'Parent' but required in type 'Child'
- 简单类型2(联合类型)
type One = string type Two = string | number type Three = string | number | boolean let one:One = '' let two:Two = 2 let three:Three = false one = two // error,如你所见,two 可能会是 number,所以类型不安全 one = three // error,类似上理 two = one // ok two = three // error,类似上理 three = one // ok three = two // ok
- 复合类型
如下,可以看到类型
Parent
之于 Child
与复合类型 Comp<Parent>
之于 Comp<Child>
具有一致性(所谓协变Covariance):type Parent = { name: string } type Child = { name: string age: number } type Comp<T> = T[] let p: Parent = { name: 'parent' } let c: Child = { name: 'child', age: 1 } let cp: Comp<Parent> = [p] let cc: Comp<Child> = [c] p = c // ok c = p // error: missing 'age' cp = cc // ok cc = cp // error: Type 'Parent' is not assignable to type 'Child' cp = [c] // ok cc = [p] // error: Type 'Parent' is not assignable to type 'Child'
- 函数
在函数中,
(p: Parent)=>void
之于 (c: Child)=>void
却与 Parent
之于 Child
正好相反(所谓逆变Contravariant):type B = (a: A | A[]) => void const b1: B = (a: A) => { } // error: Type 'string[]' is not assignable to type 'string' const b2: B = (a: A[]) => { } // error: Type 'string' is not assignable to type 'string[]' type Parent = { name: string } type Child = { name: string age: number } type FuncParent = (p: Parent) => void type FuncChild = (c: Child) => void let p: Parent = { name: 'parent' } let c: Child = { name: 'child', age: 1 } let fp: FuncParent = (p) => { } let fc: FuncChild = (c) => { } p = c // ok c = p // error: Property 'age' is missing in type 'Parent' but required in type 'Child' fp = fc // error: Type 'Parent' is not assignable to type 'Child' fc = fp // ok
从安全层面考虑:假设如果
fc
可以赋值给 fp
,那么类型约束是按照 Parent
来的,但是实际调用时,却是使用的Child
来调用,此时如果假设 fc
里依赖 c.age
,那肯定会有问题了(按 fp
来检查,无法保证 age
是存在的)。注意:仅在 tsconfig#strictFunctionTypes 开启时才会成立。
本节参考
- Catalog
- About
0%