类型断言
- A兼容B或B兼容A,可使A被断言为B
- 联合类型可被断言为其中一个类型
- 父类可断言为子类,子类也可断言为父类
- any可断言为任意类型, 任意类型可断言为any
语法:as newType或<>,将变量的已有类型断言为新类型,在typescript类型分析不符合预期,将其断言为正确类型
interface user {
name: string
}
let User = {} as user
let User: Partial<user>
将父类断言为具体的子类
class b extends a {
id: number = 0
}
class c extends a {
name: string = 'x'
}
const isB = (param: a) => {
if ((param as b).id) {
return true
}
return false
}
当原类型和断言类型差异过大,例如将string断言为number,会类型报错,这时应先断言到unknown或any类型,再断言到预期类型
// 双重断言
const str: string = 'name'
let num = str as unknown as number
num = 1 // console.log(num) 1
// 非空断言 !
declare const userInfo: {
prop?: () => ({
name?: string
})
}
userInfo.prop!().name!
const断言
用const代替类型名称断言构造新的文字表达式,表示:
- 该表达式中的字面类型不应被扩展(不能从'xx'转换为string)
- 对象字面量获取只读属性
- 数组文字成为只读元组
let a = 'x' // let a: string
const b = 'x' // const b: 'x'
let c = 'x' as const // let c: 'x'
interface user {
name: string,
age: number
}
const info = (n: number) => {
return {
name: 'x',
age: n
} as const
}
const a = info(1) // info(n: number): { readonly name: "x"; readonly age: number; }
const arr = [1,2,3]
arr.push(4) // [1, 2, 3, 4]
const arr1 = [1,2,3] as const
arr1.push(4) // Property 'push' does not exist on type 'readonly [1, 2, 3]'
显示赋值断言/非空断言操作符
在实例属性和变量声明之后加一个!,表示这个变量确实已被赋值
function initialize() {
x = 10
}
let x: number
initialize()
console.log(x + x) //- Variable 'x' is used before being assigned.
function initialize() {
x = 10
}
// notice the !
let x!: number
initialize()
console.log(x + x) // no error
在上下文中当类型检查器无法断定类型,“!”可以用于断言操作对象是非null和非undefined类型的。
type entity = {
name: string
}
function validate(e?: entity) {
let a = e.name // e是null或无效实体,就会抛出异常 'e' is possibly 'undefined'
}
function process(e?: entity) {
let a = e!.name
}
断言签名
- 断言函数:在非预期结果时抛出一个错误
- 一种断言签名模拟了断言函数的功能,确保在断言范围内,无论什么判断条件都必须为真
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg)
}
}
// 如果assert函数成功返回,则传入的condition必须为真,否则就会抛出一个Error
- 另一种断言签名不通过检查条件语句实现,而是在typeScript显示指定某个变量或属性具有不同类型
function assertsIsString(val: any): asserts val is string {
if (typeof val !== "string") {
throw new Error("not a string")
}
}
// "asserts val is string" 保证函数调用后,传入的任何变量都可以被视为是string类型
导入断言
import obj from "obj.json" assert { type: "json" }
// typescript允许, 但浏览器可能报错
动态的import()调用可以通过assert属性使用导入断言(assert类型为ImportCallOptions)
const obj = await import("obj.json",{
assert: { type: "json" }
})