TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
一般做法就是在变量的名,参数名,函数名
后面需要添加类型,这个类型添加的方法就是在其后面加:数据类型
,也就是添加约束。
var obj: { a: number, B: string, c: boolean } = { a: 1, B: "a", c: true }
console.log(obj);
var obj1: { a: number, b: { c: number, d: Array<number> } } = { a: 2, b: { c: 4, d: [1, 2, 3] } }
console.log(obj1);
interface
来定义接口(数据类型)interface IObj {
a: number,
b: {
c: number,
d: Array<number>
}
}
var obj2: IObj = { a: 2, b: { c: 2, d: [1, 2, 3] } }
第一种统一使用Function
,无法知道函数的参数和返回
var fn:Function=function fn(a: number): void {
}
第二种直接定义,使用(参数)=>返回类型
这种方式,因为前面已经有了:
所以后面的返回值使用=>
var fn: (a: number) => void = function (a: number): void {
}
第三种独立定义接口, 函数(参数):返回数据类型
interface IFn {
(a: number): void
}
var fn: IFn = function (a: number): void {
}
第四种类型,如果在对象中的函数,函数是有名称的,直接使用函数名(参数类型):返回值类型
interface Ifn {
a: number,
// b: (a: number) => void,
b(a:number):void
}
var obj:Ifn={
a:1,
b:function(a:number):void{
}
}
接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?
符号。
可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误。
对象
var obj: { a: number, b?: number } = { a: 1 }
声明式函数
function fn(a:number,b?:number):void{
}
对象中的函数
interface IObj {
a:number,
//一旦对象中这个方法可选,则必须使用?:(参数)=>返回类型
c?: (a: number) => void
}
var obj:IObj = {
a:3,
c:function(a:number):void{
}
}
interface Point {
readonly x: number;
readonly y: number;
}
var p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
var obj:Iobj={
// a属性必须只读
a:1,
b:[{a:1,b:2},{b:3,c:4},{a:3,c:6}],
c:{
d:function(a:number,b?:number)
{
return a+1;
},
// 这个函数可有可无
e:function(){
}
}
}
按要求创建以上代码的一个对象字面量接口
interface Iobj {
readonly a: number,
b: Array<{ a?: number, b?: number, c?: number }>,
c: {
d: (a: number, b: number) => number
e?: () => void
},
}
也就是对所有的属性类型做一个统一标准,而且是最高的标标准。
注意不要和可索引的类型混淆
var obj: { [key: string]: number } = {};
obj.a =12
obj.c =89
console.log(obj);//{a: 12, c: 89}
interface Iobj{
// a:string
//遵循最高标准额外属性
[key:string]:number;
}
var obj:Iobj = {
a:9,
b:2
}
这样专指数组
var arr:Array<{a:number,b:number}>=[{a:1,b:2},{a:2,b:3}];
通过创建字面量接口
interface IArr{
[index:number]:{a:number,b:number};
}
这样要是列表类型的也可以检测,包括数组
var arr:IArr=[{a:1,b:2},{a:2,b:3}];
——实现接口
类如果实现某个接口(契约),那么这个类就必须有这个接口属性和方法。
那么它就是针对这个类去约束,约定实现implements
接口的某些规定。
把两个没有关系的类加一个关系,进行共同处理
创建一个接口,规定必须有updata方法,返回值为void
interface Iop {
updata(): void
}
class Box implements Iop{
updata(): void {
console.log("Box");
}
}
class Ball implements Iop{
updata(): void {
console.log("Ball");
}
}
var b:Box=new Box();
var c:Ball=new Ball();
var b:Box=new Box();
var c:Ball=new Ball();
如果将生成的对象放在这个数组中
var arr:Array<Box|Ball>=[b,c];
以接口为类型描述数组元素
var arr:Array<Iop>=[b,c];
遍历数组,这个item添加接口描述
arr.forEach((item:Iop)=>item.updata())
一个类。可实现多个接口,即可处理多种关系
interface IA{
a:number;
play():void;
}
interface IB{
b:number;
run():void;
}
interface IC{
c:number;
}
class Box implements IA,IB{
a:number=1;
b:number=2;
constructor(){
}
run(): void {
}
play(): void {
}
}
class Ball implements IA,IC
{
a:number=2;
c:number=2;
constructor(){
}
play(): void {
}
}
var arr:Array<IA>=[new Box(),new Ball()];
通过一个接口,让类实现接口,从而让各类之间有关系
这里的 IUpdate 类型就是一种相同的联系
interface IUpdate{
update():void;
}
class Box implements IUpdate{
constructor(a:number){
}
update():void{
}
}
class Ball implements IUpdate{
constructor(a:number){
}
update():void{
}
}
在这里使用 new ()的接口意味着是一个构造函数,这个构造函数new出的实例化对象我不确定,但是他们都是IUpdate类型
interface ID{
/* new 了之后才返回IUpdate */
new (a:number):IUpdate;
}
/* 目的是传入一个参数为类名,返回一个对应的实例 */
function fn(className:ID):IUpdate{
var d:IUpdate=new className(3);
return d;
}
将类名作为参数传入
目的是传入一个参数为类名,返回一个对应的实例
console.log(fn(Box));
console.log(fn(Ball));
后面有泛型讲解,原理一样
类实现
interface IA{
a:number;
}
interface IB extends IA{
b:number;
}
class Box implements IB{
b:number=1;
a:number=2;
}
对象约束
interface IA{
a:number;
}
interface IB extends IA{
b:number;
}
var obj:IB = {
b:1,
a:2
}
接口只是把属性名和属性类型拿过来了。并没有把属性值(实现内容)拿过来。
注意别和类的继承搞混淆
class Box{
a:number=1;
b:number=2;
play():void
{
console.log("play")
}
}
接口IA继承Box类的属性和属性类型
interface IA extends Box{
c:number;
}
class Ball implements IA{
c:number=1;
a:number=2;
b:number=3;
play():void
{
console.log("cc");
}
}
interface IB {
(a: number): number;
a: number;
}
function fn():IB{
/* 如果不写,说明不了这个返回值是一个IB类型 */
var f:IB = <IB> function(a:number):number{
return a;
}
f.a = 10;
return f;
}