暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

TypeScript 4.3: 让同一属性的 getter、setter 支持不同的类型声明

背井 2021-05-15
1432

标题不容易理解,我们举一个具体的例子:

假如 User
对象有一个 age
属性,当访问 user.age
时,返回的总是 number
类型的值;设定 user.age
时,可以传入一个 number
类型的值,也可以传入 string
类型的值。类似下面这样:

const user: User = ???;// 不报错user.age = 18;// 不报错user.age = '18';// 总是 number 类型user.age;

问题来了,怎么定义 User
类型?

为此,TypeScript 4.3 引入了一个新的语法特性 *Separate Write Types on Properties*[1]

基于该语法,User
类型可以编写如下:

type User = {    // getter 总是返回 number 类型    get age(): number;    // setter 同时支持 number 和 string 类型    set age(value: number | string);}

在 TypeScript Playground 效果如下:

为使文章完整,这里也提供一个完整的 User
实现:

function makeUser(): User {    let age = 0;    return {        get age(): number {            return age;        },        set age(value: string | number) {            const num = Number(value);            // Don't allow NaN and stuff.            if (!Number.isFinite(num) || num < 0) {                age = 0;                return;            }            age = num;        }    }}

这样,实例化一个 User
对象时,只需如此:

const user = makeUser();

一个注意事项是, getter
返回的类型必须是兼容 setter
的入参类型(前者的类型是后者的一个子集)。这是为了保证同一类型可以赋值给自己。比如下面这种声明就是错的:

type User = {
    get age(): number;
    set age(value: string);
}

毕竟,我们很难想像,既然 age
number
类型,为什么不支持将 number
类型的值赋值给它呢?

留给读者一个思考:为什么要支持这类语法特性?(官方介绍中有给出理由。)


关于 TypeScript 4.3 的其它特性,可以读文末的参考资料自行学习。

参考资料

[1]

Separate Write Types on Properties: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-rc/#separate-write-types


文章转载自背井,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论