ES6的class能和函数表达式那样声明类型吗?
像函数有两种定义类型的方式:
// 函数声明
function sum1(x: number, y: number): number {
return x + y;
}
// 函数表达式
let sum2: (x: number, y: number) => number = function (x, y) {
return x + y;
};
那ES6的class能支持第二种的类型定义方式吗?比如下面这个例子的CustomType:
class Clazz1 {
static read(arg: string): void {}
constructor(arg: string): void {}
save(arg: string): void {}
}
const Clazz2: CustomType = class {
static read(arg) {}
constructor(arg) {}
save(arg) {}
}
回答
不知道你想问的是什么,是问Typescript中表达一个类的写法有没有多种吗
因为从本质上来说,虽然可以使用不同的语法去定义同一种类型,但是不同的语法所表达的含义也是不同的。
比如你举例的函数类型声明,虽然在你的例子中看似是等价的,但是看看下面这种情况呢?
// 函数声明
function sum1(x: number, y: number): void {
return x + y;
}
// 函数表达式
let sum2: (x: number, y: number) => void = function (x, y) {
return x + y;
};
注意函数的返回类型从number
修改为了void
。应该能注意到,在这个例子中,sum1
的返回值将会报告错误。
对于sum1
而言,申明了这个函数的完整类型,所以不管是参数还是返回值都将被类型约束。只要有不符合的类型就会报错;
对于sum2
而言,并未申明匿名函数的类型,而是申明了sum2
这个变量的类型。当匿名函数被赋值到sum2
时,进行类型推导,只要类型没有不兼容的部分(注意不是约束),那么就不会报错。
所以,如果是问完全与类申明等同的,那肯定没有。
如果你只是问,有没有其他类的申明方式,那么是有的。比如
interface Clazz2 {
save(arg);
}
interface Clazz2Constructor {
new (arg): Clazz2;
read(arg);
}
type StaticRead = Clazz2Constructor["read"];
type Clazz2Instance = InstanceType<Clazz2Constructor>; // Clazz2
type save = Clazz2Instance["save"];
不能。
而且你理解有误,并不存在什么两种函数的声明方式,只有一种。
你所谓的第二种,其实还是普通声明,但是加上了个赋值语句。
// 一个有名字的函数
function foo() { /* do sth */ }
// 一个匿名函数,跟上面的区别仅仅是有没有名字的区别
(function() { /* do sth */ })
// 赋值 number
let num;
num = 0;
// 赋值 string
let str;
str = 'Hello World';
// 赋值 function
let func;
func = (function() { /* do sth */ }); // 赋值成匿名函数时,包裹字面量的括号此时可省略
func = function foo() { /* do sth */ }; // 赋值成一个有名字的函数也完全没问题