从C#到TypeScript - 接口

从C#到TypeScript - 接口

为了更好的抽象出行为和属性,TypeScript在ES6的基础上增加了接口interface。 C#也有interface,不过TypeScript的接口还不大一样,C#里的接口一般是为类服务,让类实现接口中定义的方法或属性。 TypeScript在C#基础上更进一步,由于JavaScript是门非常灵活的语言,TypeScript作为JavaScript的超集需要保持灵活性,所以接口在TypeScript里可以脱离具体的类,单独作为类似契约的存在,接口里的属性也并非一定需要实现。

类的接口

这和C#的差不多,描述了公共的成员;不过实现接口语法有点类似于Java,用的是implements。

interface Selectable {
    isSelected: boolean;
}

class Control implements Selectable {
    isSelected : boolean;
}

同C#一样,接口可以多重继承其他接口,用的是extends。

interface Editable {}
interface Deleteable {}

interface Changeable extends Editable, Deleteable {}

接口的属性

接口的属性可以定义为readonly,这个和C#里只有get没有set的属性有点像,同样,实现接口的类也不一定需要readonly

interface Selectable{
    readonly isSelected: boolean;
}

class Control implements Selectable{
    isSelected: boolean;
}

let s: Selectable = { isSelected : true };
s.isSelected = false; // 编译出错, readonly

let c: Control = { isSelected : true };
c.isSelected= false; // 没问题

另外,接口还支持可选属性,同C#的可空属性一样,用?表示,实现接口的类可以不用实现可选属性。

interface RequestConfig {
    url: string;
    body?: any;
}

class Request implements RequestConfig {
    url: string;
}

接口不需要类的支持

在C#里面,接口如果没有类来实现的话是没有什么意义的,但在TypeScript里不一样,接口可以单独使用。

interface RequestConfig {
    url: string;
    body?: any;
}

let config: RequestConfig = {url: 'www.google.com'};

这种经常用在函数的参数上面,用来描述具体的参数,把具体的参数放到接口里,方便操作,也方便重构。

function Request(config: RequestConfig){

}

接口除了描述属性外,还可以用来描述函数,不过一个接口只能描述一个函数,描述时定义好参数和返回值即可。 从实现上看有点类似于C#的delegate

interface CheckLogin {
    (name: string, pwd: string): boolean;
}

let check: CheckLogin = function(name: string, pwd: string): boolean {
    return false;
}

另外,接口还可以用来描述可索引类型,就有点类似C#的Dictionary。 索引支持两种:numberstring

//定义一个Dict,key是string,value也是string
interface Dict {
    [key: string] : string;
}

let dict: Dict = { 'key1': 'value1', 'key2': 'value2'};
console.info(dict['key1']); // value1
console.info(dict['key']); // undefined

接口继承类

这在C#中很不可思议,接口居然还可以反过来继承类,不过对于JavaScript里来说,灵活方便很重要,所以TypeScript实现了这个功能来快速生成一个接口。 虽说在比较复杂的继承关系时可能会有用,不过个人认为这个功能还是有点鸡肋,因为复杂的继承通常会引入一些问题如紧耦合,牵一发而动全身,再加上这个,可能更让人摸不着头脑,不如用组合来得好。 接口继承类时会继承类中所有的成员,不管是private,protected还是public,只是不包括其实现。 不过继承了一个类不公开成员的接口只能被该类或该类的子类实现。

class User{
    name: string;
    protected pwd: string = "123";
}

class Admin extends User{
    constructor(n: string, p: string){
        super();
        this.name = n;
        this.pwd = p;
    }
}

interface UserConfig extends User{ //这里包含了name和private的pwd
}

let config: UserConfig = new Admin('brook', '123');

泛型

TypeScript是同C#一样支持泛型的,而且在使用方面也差不多,在接口名后面加上<T>即可。

interface Testable<T> {
    field: T;
    (arg: T): T;
}

也支持泛型约束,关键字是extends

interface Testable<T extends Object> {
    field: T;
    (arg: T): T;
}

TypeScript的接口对于C#程序员来说是有点奇怪了,不过用过之后还是发现非常符合JavaScript语言灵活的特性。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏醒者呆

掌握一门语言Go

摘要:Go语言的优势不必多说,通过本篇文章,让我们花时间来掌握一门外语,Let's Go! 关键字:Go语言,闭包,基本语法,函数与方法,指针,slic...

4359
来自专栏Golang语言社区

动手实现一个JSON验证器(上)

分析 既然要验证JSON的有效性,那么必然需要清楚的知道JSON格式,这个在JSON官网已经给我们画出来了: ? ? ? ? ? 从官方的图上面可以看出,JSO...

5307
来自专栏游戏杂谈

JavaScript立即调用的函数表达式

主要参考知乎上这个问题:javascript 匿名函数有哪几种执行方式 长天之云的回答。

1292
来自专栏GreenLeaves

Vue.js系列之四计算属性和观察者

一、计算属性 1、模版内的表达式非常便利,但是设计它们的初衷是用于简单计算的。在模版中放入太多的逻辑运算会让模版过重且难以维护,例如如下代码: <div id=...

2436
来自专栏编舟记

Java内部类的异常处理

最近遇到一个问题,使用Java写某个DSL标记语言X的parser(解析器)Maven插件的时候,对外暴露一个名为Callback的接口和一个待实现的方法get...

842
来自专栏漫漫全栈路

JSON学习笔记

JSON学习笔记 Web学习笔记之——Json ---- 什么是JSON JSON: JavaScript Object Notation(JavaScri...

3454
来自专栏君赏技术博客

ClangFormat语法1.0

AllowShortIfStatementsOnASingleLine (bool)

1143
来自专栏前端桃园

JavaScript ES6  让我们写得少,做得多

JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读。它允许您编写更少的代码并执行更多操作。 ES6 向我们介绍了许多强大的功能...

1152
来自专栏Java后端技术栈

Java多线程编程-(20)-借ThreadLocal出现OOM内存溢出问题再谈弱引用WeakReference

在上几篇的时候,已经简单的介绍了不正当的使用ThreadLocal造成OOM的原因,以及ThreadLocal的基本原理,下边我们首先回顾一下ThreadLoc...

1182
来自专栏DOTNET

.Net多线程编程—System.Threading.Tasks.Parallel

System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach...

41513

扫码关注云+社区

领取腾讯云代金券