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

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

假如 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 效果如下:

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

为使文章完整,这里也提供一个完整的 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);
}

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

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


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

参考资料

[1]

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


原文始发于微信公众号(背井):TypeScript 4.3: 让同一属性的 getter、setter 支持不同的类型声明

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246944.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!