//1. let list : number[] = [1,2,3]
//2. let list : Array = [1,2,3]
let x : [string,number ]
x = ['hello',10] 这样写是可以的 如果里面的反过来就不行了 也可以 x[0].toString调用字符串的方法
也可以x[ 3 ] = 'yee' 给一个不存在的赋值(只有ts3.0版本之前可以这样做 之后就不行了 通过不了编译) 但是不能赋不是定义的string number这两种之外的值
enum Color {
Red = 1,
Green = 3,
Blue = 5
}
let colorName: string = Color[2]
console.log(colorName) // Green
枚举默认从零开始 也可以自定义 比如这里都自定义第一个为1 如果后面不写的话就默认从1开始 后面两个是2,3 可以通过 Color.Green来获取 3 也可以通过color[2]来反查
function warnUser(): void{
console.log('this is a ')
}
上面的可以给函数赋void的类型 通常情况下 let unusable:void = undefined 这种是没有意义的 而且void也只能赋 undefined 和 null
function error(message:string): never{
throw new Error(message)
}
function fail(){
return error('something failed')
}
function inifiniteloop() :never{
while ( true){ //无限循环的函数也可以使用nevers
}
}
declare function create(o: object | null) : void;
上述语句的意思是 declare声明 一个函数 它的参数是object类型或者 null类型 它的返回值是void(没有返回值)
create(o:{prop: 0})
create(o:null)
上面两种都是对的
create(o:42)这种就不行了
let someValue: any = 'this is a string'
let strLength: number = (someValue).length
let strLength: number = (someValue as string).length
以上两种方法都是强制把someValue变量转为string类型
interface Square{
color: string
area: number
}
interface SquareConfig{ 后加?代表可选类型
color?: string
area?: number
}
function createSquare(config: SquareConfig): Square{
return newSquare //这个返回值必须跟Square中对应上
}
let mySquare = createSquare(config:{color:'black'}) //这里不传area也可以 因为它是可选属性
interface Point{
readonly x: number //这里 readonly就是只读属性的设置
readonly y: number
}
let p1: Ponit = { x: 10,y: 20}
p1.x = 5 //这里就会报错了 因为只读属性不能重新赋值
通过ReadonlyArray可以对数组做只读类型的定义 不过也可以使用as 做改变
interface SearchFunc {
(source:string,substring:string):boolean
}
let mySearch:SearchFunc
mySearch = function(src,sub){
let result = src.search(sub)
return result>-1
}
//也可以指定数组的索引签名 例如
interface NumberDictionary {
[index: number]: string
length: number
name: string
}
let myArray: NumberDictionary = ['ALICE','BOD'] //这个时候通过 myArray = 'Mallory' 不会报错 但是如果赋值为number类型的 就会报错了
class Animal {
name : string;
constructor( name: string){
this.name = name
}
move(distance: number=0){
console.log(`${this.name} mode ${distance}m`)
}
}
class Snake extends Animal {
constructor(name: string){
super(name) //子类继承必须要写的 如果需要调用父类的时候
}
move(distance: number = 5){
console.log('Slithering...')
super.move(distance) 调用父类的方法
}
}
let tom : Animal = new Snake('name save')
tom.move() 调用父类方法
let animal = new Animal(name:'goad');
let rhino = new Rhino()
let employee = new Employee(name:'bonb')
animal= rhino //true
animal = employee ///false
上述的三个2是1的子类 同时2里面只有constructor里有个super 3跟1的结构一样 但是他们的来源是不一样的
let passcode = ' secret1 passcode'
class Employee {
private _fullName: string; //私有变量一般前面用下划线标示
get fullName(): string { //调用私有变量的时候触发get方法
return this._fullName
}
set fullName(newName: string){//修改的时候执行里面的逻辑
if()。。。。else()...
}
}
let employee = new Employee
employee.fullName = 'bob smith'
//以下例子是利用勾股定理公式计算
calss Grid {
static origin = {x:0;y:0}
scale: number
constructor(scale: number){
this.scale = scale
}
calculateDIstanceFromOrigin(point: {x:number;y:number}){
let xDist = point.x - Grid.origin.x //静态属性访问
......
}
}
let grid1 = new Grid(scale:1.0)
console.log(grid1.calculateDIstanceFromOrigin(proint:{x:3;y:4}))
abstract class Department {
name: string
constructor(name: string){
this.name = name
}
printName(): void{
console.log('Department name')
}
abstract printMeeting():void
}
class AccountingDepartment extends Department {
constructor(){
super('Accounting ad')
}
printMeeting():void{
console.log('the account')
}
genterateReports(): void {
console.log('Generating')
}
}
// let department: Department
let department: AccountingDepartment
department = new AccountingDepartment()
department.printName()
department.printMeeting()
department.genterateReports()//报错 因为let department: Department department只中没有这个
//如果想要不报错把let department: AccountingDepartment这样就行了
class Greeter {
static standardGreeting = 'Hello, there'
greeting: string
constructor(message?: string){
this.greeting = message
}
greet() {
if(this.greeting) {
return 'Hello' + this.greeting
} else {
return Greeter.standardGreeting
}
}
}
let greeter: Greeter // greeter的类型是定义的类
greeter = new Greeter()
let greeterMaker: typeof Greeter = Greeter//生成一个新的构造器来更改静态属性值
greeterMaker.standardGreeting = 'Hey there'
let greeter2: Greeter = new greeterMaker()
console.log(greeter.greet())
class Point {
x: number
y: number
}
interface Point3d extends Point {
z: number
}
let point3d: Point3d = {x:1,y:1,z:1}
function pickCard(x: {suit:string; card:number}[]): number
function pickCard(x: number): {suit:string; card:number}
//上述两个就是pickCard函数的重载 可以判断函数调用时传入的参数类型 第一个是传入数组 返回number
//第二个重载是传入数字 返回对象
function pickCard(x): any{
//里面写逻辑
if(Array.isArray(x)){
let pickedCard = Math.floor(x:Math.random() * x.length)
return pickedCard
}else if( typeof x === 'number'){
let pickedSult = Math.floor(x: x/13)
return {suit: suits[pickedSuit],card: x%13}
}
}
/使用场景 例如想要有个函数 返回任何传入的值 使传入的类型与返回的类型相同
//下面这种情况如果传入的是数字返回的是 字符串 不符合我们的需求
// function identity (arg: any): any{
// return arg + ''
// }
//T是一个类型变量可以帮我们 捕获用户传入的类型 这样的函数我们就称为泛型
function identity (arg: T): T{
return arg
}
//使用 上述 泛型函数 例如
// let output = identity('mystring')//标记T为string 传入的参数为string类型的 这样写有些亢长
//也可以直接写 泛型会自动解析
// let output = identity(arg:'mystring')
//使用泛型定义接口
// interface GenericIdentityFn {
// (arg: T): T
// }
// let myIdentity: GenericIdentityFn = identity
//定义泛型类的使用 静态类型不能使用泛型类
// class GenericNumber {
// zeroValue: T
// add: (x: T, y: T) => T
// }
// let myGenericNumber = new GenericNumber{
// myGenericNumber.zeroValue = 0
// myGenericNumber.add = function (x,y){
// return x+ y
// }
// }
//泛型类 + 泛型约束
//例如 一个函数 里面有obj key 两个参数 返回obj[key]
//这时候对obj做类型约束为T k要存在于T得属性中 所以使用 K extends keyof T
function getProperty(obj: T,key: K){
return obj[key]
}
//调用上述函数 如果调用得key在x里面没有那么会报错
// let x = {a:1,b:2,c:3,d:4}
// getProperty(x, key:'a')
//使用泛型创建工厂函数
class BeeKeeper {
hasMark: boolean
}
class LionKeeper {
nametag: string
}
class Animal {
numLengs: number
}
class Bee extends Animal{
keeper: BeeKeeper
}
class Lion extends Animal{
keeper: LionKeeper
}
//工厂函数
function createTnstance (c: new()=> T): T{
return new c()
}
createTnstance(Lion).keeper.nametag//可以调用
createTnstance(Bee).keeper.hasMark//可以调用
//交叉类型 例如把两个对象的类型组合到一起 下面我们来写这样一个函数
function extend(first: T,second: U): T & U {
let result = {} as T & U
for(let id in first){
result[id] = first[id] as any
}
for(let id in second){ //过滤掉result中已经有的id
if(!result.hasOwnProperty(id)){
result[id] = second[id] as any
}
}
return result
}
class Person {
constructor(public name: string) {
}
}
interface Loggable {
log(): void
}
class ConsoleLogger implements loggable{
log() {
// ...
}
}
let jim = extend(new Person(name:'jim'),new ConsoleLogger())
//可以调用Person中的name和ConsoleLogger
jim.name
jim.log()
function isNumber(x: any): x is number {
return typeof x === 'number'
}
function isString(x: any): x is number {
return typeof x === 'string'
}
function padLeft(value: string, padding: string | number){
if(typeof padding !== 'number'){
return Array(arrayLength:padding + 1).join('')+value
}
if(isString(padding)){
return padding + value
}
}```