前2篇有错误的原因找到了,本地的ts版本有问题,不是最新版本,是1.8。不改了,就这样写吧,以后注意~~
/**typeScript-3 interface
* Created by liyanq on 17/6/8.
*/
interface LabelledValue {
label: string;
}
function PrintLabel(labelledObj: LabelledValue): void {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
PrintLabel(myObj);//Size 10 Object
//--------Optional Properties-----------------//
/*1,createSquare的返回值虽然是{color: string; area: number}类型,但返回多些字段也可以,
不能少,少了编译器提示错误,可以理解返回值必须是实现了包涵这两个字段的接口的对象~
2,createSquare的返回值在es5中直接无视~
3,虽然有可选的字段,但访问接口定义范围外的字段,会有错误提示.~
*/
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig): {color: string; area: number} {//注意这里返回值
let newSquare = {color: "white", area: 100, age: 30};
if (config.color) {
// newSquare.color = config.c;// Error: Property 'c' does not exist on type 'SquareConfig'
newSquare.color = config.color;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
let mySquare = createSquare({color: "black"});
console.log(mySquare);//{ color: 'black', area: 100 }
//-----------Readonly properties------------//
interface Point {
readonly y: Number;
readonly x: Number;
}
let p1: Point = {x: 1, y: 1};
// p1.x = 2;//cannot assign to x because it is a constructor or a read-only property
class Foo {
b: string;//这里这么就不能设置成readonly???
constructor(hello: string) {
this.b = hello; // 在构造函数中允许赋值
}
}
let foo = new Foo("Hello");
console.log(foo);//Foo { a: 1, b: 'Hello' }
// let a: Array<number> = [0, 1, 2, 3, 4];
// let b: ReadonlyArray<number> = a;
// b[5] = 5; // 错误, 元素是只读的
// b.push(5); // 错误, 没有 push 方法 (因为它会改变数组)
// b.length = 3; // 错误, length 是只读的
// a = b; // 错误, 缺少会改变数组值的方法
// const v = { k1: 1, k2: { k21: 2 } };
// const v_ro = v as Readonly<typeof v>;
// 属性: 不可赋值
// v_ro.k1 = 2;
// 属性的属性: 可以赋值
// v_ro.k2.k21 = 3;
//-----------readonly vs const-------//
//Variables use const whereas properties use readonly.
//--------------Excess Property Checks-----------//
interface SquareConfig2 {
color?: string;
width?: number;
[propName: string]: any;
/*意思是index signatures,中括号里面只能是number或string类型.
* 自己的理解:一旦接口定义了这个方式,通过索引访问的方法,那么所有的属性都可以通过这个方法访问到,
* 并且类型能自动的隐式转换,否则接口本身就报错~~!
* */
}
function createSquare2(config: SquareConfig2): { color: string; area: number } {
let newSquare = {color: "white", area: 100, age: 30};
if (config.color) {
// newSquare.color = config.c;// Error: Property 'c' does not exist on type 'SquareConfig'
newSquare.color = config.color;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
let mySquare2 = createSquare2({coulor: "red", width: 100});//这样做,虽然绕开了检查,但也失去了type语言的意义了~~!
// let mySquare2 = createSquare2({coluor: "red", width: 100} as SquareConfig);//这个可以躲过编译器的警告~
console.log(mySquare2);
//------------Function Types------------//
/*
* 1,在函数类型正确的通过类型检查中,参数的名称不是必须匹配的。*/
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function (source: string, subString: string): boolean {
let result = source.search(subString);
return result > -1;
};
console.log(mySearch("Hello", "H"));
//------------------Indexable Types--------------//
/*错误, 'length'的类型不是索引类型的子类型
* 索引类型是string,length的类型是number
* */
interface Dictionary {
[anyname: string]: string;
length: string;
}
//-----------------Class Types--------//
/*1,接口定义的方法和字段,在类里面都必须public
* 2,当用一个类来实现一个接口时,只检查该类的实例部分。由于构造函数位于静态部分,它不包含在该检查中。*/
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
currentTime: Date;
public setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {
}
}
//------------类的静态部分和实例部分的差异-----------------//
interface ClockStatic {
new (hour: number, minute: number);
}
class Clock2 {
currentTime: Date;
constructor(h: number, m: number) {
this.currentTime = new Date(2017, h, m);
}
}
var cs: ClockStatic = Clock2;
var newClock = new cs(7, 30);
console.log(newClock);
//----------------接口扩展--------------//
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
var square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
//--------------混合类型-----------//
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function counter(): Counter {
var self = <Counter>function (start: number) {
self.interval = start;
console.log("Hello World " + start);
};
self.interval = 10;
self.reset = function () {
self.interval = 10;
};
return self;
}
var c = counter();//c.interval = 10
c(5); //c.interval = 5
c.interval = 15; //c.interval = 15
c.reset(); //c.interval = 10
/*我个人觉得这样写不太好,还是声明成类,然后创建对象的方式比较正规*/
interface Counter_New {
funStart(start: number): void;
reset(): void;
interval: number;
}
class Counter_Class implements Counter_New {
interval = 10;
funStart(start: number): void {
this.interval = start;
console.log("Hello World " + start);
}
reset(): void {
this.interval = 10;
};
}
var c2 = new Counter_Class();
c2.funStart(20);
c2.interval = 15;
c2.reset();
//待研究
// interface UIElement {
// addClickListener(onclick: (this: void, e: Event) => void): void;
// }