基础变量类型
let 变量名: 变量类型 = 值
let num: number = 10
let str: string = '10'
变量类型有 number string boolean object Array undefined null any void never
特殊:
**undefined 和 null 可以赋值给任意类型,只可以被undefined,null和never赋值**
num = '10' (不行)
num = unll (行)
num = undefined (行)
**any 可以被任意类型赋值**
let ANY: any = 10
ANY = '10' (行)
ANY = [1,2,3] (也行)
**never 类型**
nener 也可以作为任意类型的子类,像undefined和null一样可以赋值给任意类型,但不可被任意类型赋值
never 类型表示的是那些永不存在的值的类型,必须有无法到达的终点
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
数组与元组
定义数组的两种方式
let 变量名:元素类型[] = 值
let arr: number[] = [1,2,3,4] //arr中元素只能为number
let 变量名: 类型<元素类型> = 值
let arr: Array<string> = ['1','2','3','4'] //arr中元素只能为string
定义元组
元组比数组更"死板"一些,适合按类型存有限个值
let list: [number, string] = [19, 'LLC']
枚举enum
enum Color {
red,
blue,
green
}
枚举的起始值默认是0然后递增,即:
log(Color.red) //0
log(Color.blue) //1
log(Color.green) //2
也可自定义起始
enum Color {
red=10,
blue,
green
}
或自定义所有值
enum Color {
red=10,
blue=100,
green=20
}
元组可以"双向查找":
log(Color[10]) //red
log(Color.red) //10
let c: Color = Color.Green;
let colorName: string = Color[2];
类型断言
//断言的运用场景
求参数的长度,参数可能是number也可能是string
function getLength(parmaeter: string|number): number {
return parmaeter.toString().length; //但这不合理,当parmaeter是string时不应该再toString()
}
应该
function getLength(parmaeter: string|number): number { //参数可能是string和numbe类型
if ((<string>parmaeter).length) { //此处断言(向编译器"保证")参数是string类型来看他的长度,当然若保证错了(他不是string)那么parmaeter.length就是undefined那就不执行这一段代码
return (<string>parmaeter).length //实际上如果参数是number则不会有长度,就不会执行这一块代码,如果参数真的是string则成功执行
} else {
return parmaeter.toString().length //当上面没有找到参数长度时,说明参数不是string,则执行这一段
}
}
断言的两种申明方式
(<类型>变量名) //(<string>name)
(变量名 as 类型)//(name as string)
接口
interface PERSON {
name: string
age: number
}
const USER: PERSON = { //定义一个PERSON类型user对象,必须 "有且仅有" PERSON里的属性
name: 'LLC',
age: 19
}
接口只读属性 readonly
interface PERSON {
readonly name: string //只能在前面加readlonly
age: number
}
USER.name = "RBY" //不允许
接口可有可无属性在后面加个问号 ?
interface PERSON {
name: string
age?: number //age属性可有可无
}
const USER: PERSON = {
name: "LLC"
age属性可有可无
}
函数类型
interface GET_INFO {
(Info: object, attr: string) : string
}
定义函数的类型为GET_INFO 函数必须具有相同的参数和返回值 (Info: object, attr: string) : string
const getInfo: GET_INFO = (Info: object, attr: string) : string => Info[attr]
类 类型
//接口与接口之间叫继承extends; 类与接口之间叫实现 implements
interface FLY {
fly() //ES6语法糖,fly方法
}
interface SWIM {
swimming()
}
class Person implements FLY, SWIM { //实现两个接口,必须具有所有接口中的类型 (一个类可以同时被多个接口约束)
fly() {
console.log('I can fly');
}
swimming() {
console.log('I can swim');
}
}
**接口之间的继承**
interface BEHAVIOUR extends FLY, SWIM{ //继承两个接口 (一个接口可以同时继承多个接口)
say()
}
class Person implements FLY, SWIM { //必须具有所有BEHAVIOUR 接口中的类型
fly() {
console.log('I can fly');
}
swimming() {
console.log('I can swim');
}
say() {
cosnole.log('I can speak');
}
}
类
class Person {
//提前定义name,gender属性的类型
name: string
gender: string
constructor(name: string = "佐助", gender: string = "meal") { //还可以设置默认值
this.name = name
this.gender = gender
}
say(): void {
console.log(`I am ${this.name}, I am a ${this.gender === "meal" ? 'girl' : 'boy'}`);
}
}
const P = new Person();
P.say()
继承 extends
//类与类之间叫继承 extends 子类可以用,不用,改写父类方法/属性,但是不论用不用,他都继承过来了
class Person {
name: string
gender: string
constructor(name: string, gender: string) {
this.name = name
this.gender = gender
}
talk(): void {
console.log('I can talk');
}
}
class Student extends Person {
constructor(name: string, gender: string) {
super(name, gender)
}
talk(): string { //重写父类方法1
console.log('I am good at talking');
return 'I am good at talking'
}
talk(): string{ //重写父类方法2
super.talk()
return 'I am good at talking'
}
//也可不写父类方法,子类也默认可用父类方法
study(): void {
console.log('I ccans study');
}
}
const LLC = new Student("LLC", "meal");
LLC.talk()
LLC.study()