TypeScript$Variable-Declaration-AnnotateAndInferAndAssertion

148 阅读2分钟

TypeScript$Variable-Declaration-AnnotateAndInferAndAssertion

1. Annotate and Infer and Assertion

在 TypeScript 中,声明变量(值)类型的方式有三种:

1. Annotate

显示地声明变量的类型(通过 :type):

let name: string = 'Md'

2. Infer

不声明类型,由系统自动推断:

let name = 'Md' // 自动推断 name 的类型是 string
const humidity = 79 // iteral type: 79
let age // 如果不赋值, 类型为 any

3. Assertion: as and satisfies

通过 as type 来转换类型(所谓的转换,是指让 TypeScript 以为类型变了,其实没变):

const humidity = 79 as number
let age = 100 as const
let date1 = "oops" as any as Date // 可以向上转,但不能向下转
let date2 = "oops" as unknown as Date // 可以向上转,但不能向下转
let num = 18 as string // error, number 和 string 不兼容

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
// except if the code is in a `.tsx` file
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");

satisfies type 能正确地判断可选属性:

interface box {
  a: string,
  b?:string
}
let box1 = {a: 'a', b:'b'} satisfies box
let box2 = {a: 'a'} satisfies box
let box3 = {a: 'a', b:'b'} as box
let box4 = {a: 'a'} as box
console.log(box1.b.toUpperCase)
console.log(box2.b.toUpperCase) // error
console.log(box3.b.toUpperCase) // error
console.log(box4.b.toUpperCase) // error

2. Annotate or Infer

声明变量的时候,是显示地声明还是隐式地声明呢?在想要声明的时候显示地声明。通常显示声明函数签名(如果函数简单的话返回值也可以不声明)。 FunctionSignature

function signature (or type signature, or method signature) defines input and output of functions or methods.。

function add(a: number, b: number): number {
	return a + b
}

对于 parameters 声明类型相信没有人会有疑问,为什么 returned value 也需要声明类型呢?返回值的类型不应该是自动推断出来的吗?

函数返回值的类型确实可以自动推断,而显示声明出来的目的,是预防编写函数的人编写错误。比如:

function calc(a: number, b: number, type: string): number {
	if (type === 'add') {
		return a + b
	} else if (type === 'sub') {
		return a - b
	} else if (type === 'multiple') {
		return a * b
	} else if (type === 'devide') {
		return a / b
	}
	return
}

如果 calc 函数没有声明返回类型,函数不会报错,返回类型是 number | undefined。但这个函数其实写错了。我们不希望返回 undefined,我们想要没有匹配 type 时返回 a + b。不声明返回类型的时候我们没有发现这个错误,而声明返回类型之后我们发现了,因此可以修正:

function calc(a: number, b: number, type: string): number {
	if (type === 'add') {
		return a + b
	} else if (type === 'sub') {
		return a - b
	} else if (type === 'multiple') {
		return a * b
	} else if (type === 'devide') {
		return a / b
	}
	return a + b
}