H5W3
当前位置:H5W3 > 问答 > 正文

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 */ }; // 赋值成一个有名字的函数也完全没问题

本文地址:H5W3 » ES6的class能和函数表达式那样声明类型吗?

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址