【问题标题】:How to best describe this code using TypeScript?如何使用 TypeScript 最好地描述这段代码?
【发布时间】:2020-04-15 04:06:11
【问题描述】:

这里是一个对象,它有几个不同的 key 和 value,每个 props 的 value 都不同,如何使用 TypeScript 最好地描述这个对象?特别是setValue方法,如何限制creatureTypepropvalue的类型?

 const object = {
      john: {
        name: '',
        age: 18
      },
      alien: {
        height: 20,
        power:100,
      },
      setValue(creatureType) {
        const self = this
        return function (prop) {
          return function (value) {
            self[creatureType][prop] = value
          }
        }
      }
    }

【问题讨论】:

  • 该方法类似于(prop: string) => (value: any) => void,但老实说,我会使用真正的二传手。如果您想在不传递引用的情况下公开它们,但没有方法返回闭包,请将它们包装在 lambda 中。您在这里将政策与实施交织在一起。
  • 对不起,我的英文不是很好,你的意思是关闭不是一个好习惯?你能举个例子吗?非常感谢
  • class Foo { bar: string }; const foo = new Foo(); export const setter = (prop: string) => (val: any) => foo[prop] = val; 该实例是模块的本地实例,这样您就不会使用访问策略来混淆类实现。不过,您可能希望使用泛型而不是 any,请参阅 jcalz 的答案。

标签: javascript reactjs typescript vue.js frontend


【解决方案1】:

你的setValue() 方法必须是generic,如果你想让它严格限制哪些属性和值与哪些,呃,“生物类型”。因为objectsetValue()方法的类型将依赖于object的其他属性的类型,编译器将放弃尝试为其推断类型;对于不是class 的东西来说,它太圆了。您可以手动注释所有类型,这会很烦人,或者您可以将 object 拆分为两部分,例如 plainObject 只保存数据,然后合并到 setValue() 方法中,这将取决于类型plainObject,像这样:

const plainObject = {
    john: { name: '', age: 18 },
    alien: { height: 20, power: 100 }
}
type PlainObject = typeof plainObject;

const object = {
    ...plainObject,
    setValue<K extends keyof PlainObject>(creatureType: K) {
        const self: PlainObject = this;
        return function <P extends keyof PlainObject[K]>(prop: P) {
            return function (value: PlainObject[K][P]) {
                self[creatureType][prop] = value;
            }
        }
    }
}

您可以验证编译器是否按照您的意愿运行:

object.setValue("john")("age")(19); // okay
object.setValue("alien")("height")("pretty tall"); // error!
// "pretty tall" isn't numeric --> ~~~~~~~~~~~~~
object.setValue("john")("power")(9000); // error!
// "power" is wrong --> ~~~~~~~
object.setValue("elaine")("name")("elaine"); // error!
// "elaine"? -> ~~~~~~~~

好的,希望对您有所帮助;祝你好运!

Link to code in Playground

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 2013-09-26
    • 2011-11-09
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 2015-04-19
    • 2015-09-06
    相关资源
    最近更新 更多