断言
as 断言
as 断言的意思就是用户断定这是什么类型,不使用系统推断的类型。
下例中TS会根据函数推断变量f的类型是string|number
function test(arg: number){
return arg?'test': 2023
}
let f = test(1) // let f: string|number我们可以由开发者来断定这就是字符串,这就是断言。
function test(arg: number) {
return arg ? 'test': 2023
}
let f = test(1) as string // let f: string也可以使用下面的断言语法
function test(arg: number) {
return arg ? 'test': 2023
}
let f = <string>f(1) // let f: stringconst 断言
let & const
- const 保证该字面量的严格类型
- let 为能用类型比如字符串类型
const t = 'test' // const t: 'test'
let x = 'test' // let x: stringconst
const断言告诉编译器为表达式推断出它能推断出它能推断出的最窄或最特定的类型,而不是宽泛的类型
- 字符串、布尔类型转换为具体值
- 对象转换为只读属性
- 数组转换成为只读元组
下面限定user类型为'test'
let user = '测试' as const
user = 'test' // error对象转换为只读属性
let user = {name: '测试'} as const
user.name = 'test' // error 因为是只读属性,所以不允许设置值当为对象值为变量时,as const后具体值类型为这个变量的类型
let a = 'test'
let b = 1 as const
let f = {
name: a,
arg : b
} as const数组赋值
变量f得到的类型是数组的类型string|number,所以只要值是这两个类型都可以
let a = 'test'
let b = 1
let arr = [a, b] // let arr: (string|number)[]
let f = arr[1] // let f: string|number
f = '测试' // ok 因为类型是 string|number使用const之后得到值的具体类型,而不是数组的类型
let a = 'test'
let b = 1
let arr = [a, b] as const // let arr: readonly [string, number]
let f = arr[1] // let f: number
f = '测试' // error 不能将类型“string”分配给类型“number”也可以使用以下语法
let a = 'test'
let b = 1
let arr = <const>[a, b] // let arr: readonly [string, number]
let f = arr[1] // let f: number
f = 199解构
下面解构得到的变量类型不是具体类型,而是数组类型,比如变量y的类型是string | (()=>void)这在写项目时是不安全的,因为可以将y随时修改为字符串,同时也不会有友好的代码提示
function test(){
let a = '测试'
let b = (x: number, y: number): number => x + y
return [a, b]
}
let [n, m] = test() // 变量 m 的类型为 string | (() => void)
m(1, 6) // error 因为类型可能是字符串,所以不允许调用可以断言m为函数然后调用
function test(){
let a = '测试'
let b = (x: number, y: number): number => x + y
return [a, b]
}
let [n, m] = test()
console.log((m as Function)(1,3))
// 使用下面类型声明也可以
console.log((m as (x: number, y: number) => number)(1,2))可以在调用时对返回值断言类型
function test() {
let a = '测试'
let b = (x: number, y: number): number => x + y
return [a, b]
}
let [n, m] = test() as [string, (x: number, y: number) => number]
console.log(m(1, 2))也可以在函数体内声明返回类型
function test() {
let a = '测试'
let b = (x: number, y: number): number => x + y
return [a, b] as [typeof a, typeof b]
}
let [n, m] = test()
console.log(m(1, 2))使用 as const 就可以很高效的解决上面的问题,可以得到具体的类型,来得到更安全的代码,同时会有更好的代码提示
function test() {
let a = '测试'
let b = ():void => {}
return [a, b] as const
}
const [x, y] = test() // 变量 y 的类型为 ()=>void因为const是取值的类型,下面代码虽然不报错,但此时b的类型已经是字符串或函数,所以像下面一样在函数调用时as const没有意义。
function test() {
let a = '测试'
let b = (x: number, y: number): number => x + y
return [a, b]
}
const [n, m] = [...test()] as const // 没有意义也可以使用泛型来处理
function test() {
let a = '测试'
let b = (x: number, y: number): number => x + y
return test2(a, b)
}
function test2<T extends any[]>(...args: T): T {
return args
}
const [n, m] = test();
console.log(m(1, 3))null/undefined
默认情况下null与undefined可以赋值给其他类型
let test: string = '测试'
test = null // 不能将类型“null”分配给类型“string”。
test = undefined // 不能将类型“undefined”分配给类型“string”。当我们修改 tsconfig.json 配置文件的 strictNullChecks 字段为 true(默认即为 true) 时,则不能将 null、undefined 赋值给其他类型
"strictNullChecks": true除非向下面一样明确指定类型
let test: string | null | undefined = '测试'
test = null
test = undefined非空断言
下面的示例获取的值可能为HTMLDivElement或null,所以直接分配类型HTMLDivElement将报错。
下例操作需要开启tsconfig.json的配置项strictNullChecks字段为true
const el: HTMLDivElement = document.querySelector('#test') //error 不能将类型“HTMLDivElement | null”分配给类型“HTMLDivElement”。
console.log(el.id)可以使用as断言类型
const el: HTMLDivElement = document.querySelector('.test') as HTMLDivElement // ok
console.log(el.id)在值后面使用!来声明值非null
const el: HTMLDivElement = document.querySelector('.test')! // ok
console.log(el.id)