【问题标题】:Is there a way to define a setter function in TypeScript?有没有办法在 TypeScript 中定义 setter 函数?
【发布时间】:2015-01-18 15:33:17
【问题描述】:

我发现以下 getter 函数非常有用且可重用,因为它可以获取具有此类属性的 any 对象的属性 key 的值。

export function keyOf<a>(value: { key: a; }) : a {
   return value.key;
}

同样我可以定义一个通用的setter函数:

export function withKey<a>(value: { key: a; }, key: a) : void {
    value.key = key;
}

唯一的问题是,我需要它返回原始对象 value 和修改后的 key 属性,而不是返回 void。像这样的:

export function withKey<b, a extends { key: b }>(value: a, key: b) : a {
   value.key = key;
   return value;
}

但这不是一段有效的 TypeScript 代码。

问题:我怎样才能获得一个类型安全的通用 setter 函数,它返回原始对象及其属性集?

更新:

在当前 TypeScript 中,类型参数之间的依赖关系是被禁止的。我相信这样做是为了使类型系统更简单、更快。但是,此限制会阻止某些有用的场景,例如所讨论的场景。有一个 hack 可以将类型参数之间的依赖关系变成函数依赖关系:

export function withKey<a, b>(
    value: a,
    key: b,
    toAssignable: (value: a) => { key: b } = function<c>(anything: c) : c {
        return anything;
    }
) : a {
    toAssignable(value).key = key;
    return value;
}

这看起来很丑陋并且改变了原始签名,但它可以编译和工作。

有人知道更好的方法吗?

【问题讨论】:

标签: typescript


【解决方案1】:

我玩了一会儿,我只能想出这个:

// === unsave approach ===  

/**
 * Test class
 */ 
class MyClassWithoutKey {
    public youCanCallThis() { }
}

/**
 * The setter function
 */
function withKeyUnsafe<T>(value: T, key: any) {
    (<any>value).key = key;
    return value;
}

// compile test
var w = withKeyUnsafe(new MyClassWithoutKey(), 2).youCanCallThis();

还有这个:

// === typesave approach ===

/**
 * Test class
 */     
class MyClassWithKey {
    key: string;
    public youCanCallThis() { }
}

/**
 * Helper interface
 */ 
interface WithKey<T> {
    key: T;
}

/**
 * Factory function that adds type constraint
 */
function withKeyTypeSave<T>() {
    /**
     * The actual setter function
     */
    return function <WithKeyT extends WithKey<T>>(value: WithKeyT, key: T) {
        value.key = key;
        return value;
    }
}


// compile test -- works
withKeyTypeSave<string>()(new MyClassWithKey(), "new key").youCanCallThis();

// compile test -- fails
withKeyTypeSave<number>()(new MyClassWithKey(), "new key").youCanCallThis();

// compile test -- fails
withKeyTypeSave<string>()(new MyClassWithKey(), 3).youCanCallThis();

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 2022-01-05
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 2017-12-28
    • 2019-08-01
    相关资源
    最近更新 更多