TypeScript 依赖的字符串文字属性和索引

2024-02-23

如同Typescript:属性的类型依赖于同一对象中的另一个属性 https://stackoverflow.com/questions/56949513/typescript-type-of-a-property-dependent-on-another-property-within-the-same-obj我想要一种属性相互依赖的类型。

const attributes = {
    physical: {
        traits: {
            strength: 1,
            dexterity: 1,
            stamina: 1,
        }
    },
    social: {
        traits: {
            charisma: 1,
            manipulation: 1,
            appearance: 1,
        }
    },
    mental: {
        traits: {
            perception: 1,
            intelligence: 1,
            wits: 1,
        }
    }
};

type AttributeTrait =
    | {
        category: 'physical';
        trait: keyof typeof attributes.physical.traits;
    }
    | {
        category: 'social';
        trait: keyof typeof attributes.social.traits;
    }
    | {
        category: 'mental';
        trait: keyof typeof attributes.mental.traits;
    };

const action: AttributeTrait = {
    category: 'social',
    trait: 'manipulation'
}

function increment(action: AttributeTrait) {
    attributes[action.category].traits[action.trait]++; // error 7053
}

在函数中,action.trait键入为:

(属性)特质:“力量” | 「灵巧」| “耐力”| “魅力”| “操纵”| 「外观」| 「感知」| 「情报」| “智慧”

所以它不能用于索引traits.

我该如何解决这个问题?


我没有为您提供非冗余且类型安全的解决方案。你的AttributeTrait我一直称之为相关记录类型 https://github.com/microsoft/TypeScript/issues/30581。这是一个可区分的联合体,其中某些代码对于联合体的每个成员都是安全的,但编译器无法看到它对于整个联合体来说是安全的,因为它失去了对联合体的跟踪。相关性在。。之间category and trait特性。

如果编写冗余代码,错误就会消失:

function incrementRedundant(action: AttributeTrait) {
    switch (action.category) {
        case "physical":
            attributes[action.category].traits[action.trait]++;
            return;
        case "social":
            attributes[action.category].traits[action.trait]++;
            return;
        case "mental":
            attributes[action.category].traits[action.trait]++;
            return;
    }
}

但是,无论您如何尝试,您都无法将这些情况折叠成一行代码并让编译器为您验证安全性。这就是我提交的原因微软/TypeScript#30581 https://github.com/microsoft/TypeScript/issues/30581,以及我提交的原因之一微软/TypeScript#25051 https://github.com/microsoft/TypeScript/issues/25051。因为你不能要求编译器处理单行as if它已被写在switch/case声明,我能想到的最好的办法就是使用类型断言 https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions告诉编译器你比它更了解。

做到这一点的一种方法是撒一点谎并告诉编译器:attributes实际上拥有所有trait全部category对象:

function increment(action: AttributeTrait) {
    (attributes as
        Record<AttributeTrait["category"], {
            traits: Record<AttributeTrait["trait"], number>
        }>
    )[action.category].traits[action.trait]++;
}

这比冗余代码的类型安全性较差,但至少它可以让您继续前进。


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

Playground 代码链接 https://www.typescriptlang.org/play/#code/MYewdgzgLgBAhlKAnAlgIwK5QKYRgXhgG8AoGcmABwAsBPCFYOAGwC5iyKvk4UoJ2pLsIrQk2MAHMo1dgEYANJxFcAJtgAeOVFFrylK4dDgBbFGDj7lwgL7WbB0SGAoWg69yS9+7w12DUcKgQJpYwih4qoWAolBjMCCjgVn4UcJSU2EFwYMDYKSp2XA7WJhJQbhyGPHwCValU2Eh5lFBJYAWp5jjMzCiSEnmdfgDutcPF9iQ2ANwkJLqZMACCiKiYOAAqXnwE1gA+9SJMOJIgSHowAOQ09IwsV3PVO1DsANbYtCAAZjCL2D94Gt0FhcAA6W4MJjMME1fhPChFCiHIQqE7YM4XdhXCDOVzMR6Rchw96fQH-QEIZAgnAQMG4lwsWEvCAI8hI8gookwdGYy5XMpgCoEtnCEkwD5fX4U35U9agumC4XM7ys+xzEigSCwODANrJFbAjbYbbeAhHHkIDHnfkM-FXRzEl7Y6KxeKJcBXabzb4YXL6sAwczAcRKgBK2FUftUOSgAApdQH2KtqcbTXwAJQWiBjKABGAJvXtMG8m1Z1HHOAQbAwABEkPuzFrrG5XDlNNwAG1E8XSxcALoq2rdovgIdQfsAaknosM4igGCQYFnFCY1brdpYzdbaSNCpHAZLVr5g7hEAPxbhU5nO-I88Xy+5a5rtaVW5bDSBqf3PbHfdop4sheY5XtOK4iPeS6inYdgkL6-rtEGuShuUhZJoa35bC85bWAme60vAEDchGoBIKoAA8Kbylh3idrW-61v2CgWs8qrsCR5wUVRHbplAdFwoxzFgBgJhoE0AB83I2JJXAZsBYBHqcNqAaq8njtecywUAA

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript 依赖的字符串文字属性和索引 的相关文章

  • 如何为 React 组件参数创建文字类型?

    我创建了 SelectProps 界面 export interface SelectProps value string options string onChange value any gt void 我创建了反应组件
  • AWS CDK CodePipeline 在源代码和构建之间添加一个阶段

    我跟着使用 CDK Pipelines 持续集成和交付 CI CD https docs aws amazon com cdk v2 guide cdk pipeline html实施 CodePipeline 的指南 我想知道如何在 CD
  • 打字总是抱怨全局模块

    我对打字稿很陌生 无论我尝试安装什么类型 我都会得到 打字错误 消息 尝试将 Angular 编译为外部模块 但它看起来像全局模块 我只是想做 typings install dt angular 我究竟做错了什么 Update 如果您对此
  • TypeScript - 如何从方法的参数推断类泛型类型?

    我正在尝试从稍后调用的方法参数中输入类泛型 在我们调用带有泛型参数的方法之前 类的泛型类型是不知道的 然后 对于任何其他方法 将传递泛型类型 老实说 对我来说 这似乎是一个非常复杂的功能 我什至不确定 TypeScript 是否有办法做到这
  • 尝试使用 ui-router 让一个子视图调用另一个子视图

    我有两个子视图 一个用于类别 一个用于产品 因此是该类别的产品 我希望用户能够选择一个类别并查看该类别的所有产品 所以我在类别控制器中调用一个函数View单击类别行上的按钮 这是函数 self scope viewSalonProducts
  • 指定枚举类型

    有枚举 enum Foo Bar should cause type error Baz Baz 可以为其指定类型以使其成为仅字符串枚举吗 如果您愿意 您可以执行以下操作 创建一个函数 要求其输入只有string 有价值的属性 const
  • 在 Angular2 (TS) 中导入模块的选项

    我知道有一些进展或至少有计划 5093 https github com Microsoft TypeScript issues 5039 5728 https github com Microsoft TypeScript pull 57
  • Typescript 类似断言的类型保护

    这是否可以在没有限制的情况下限制类型if通过函数调用never返回例如undefined like assert在打字稿中 示例代码 interface Foo bar void function getFoo Foo undefined
  • 如何在 TypeScript 中声明私有抽象方法?

    如何在 TypeScript 中正确定义私有抽象方法 这是一个简单的代码 abstract class Fruit name string constructor name string this name name abstract pr
  • Typescript 参数 - 对象的通用数组和对象键的数组(部分)

    我想要一个接受对象数组和一些对象键数组的方法 该方法将返回对象值数组的数组 但仅返回选定键的数组 data firstName Jane lastName Doe firstName John lastName Doe fields fir
  • 在 TypeScript 中生成具有单个模块的声明文件

    给定以下文件夹结构 src foo ts bar ts baz ts index ts Where foo ts bar ts and baz ts每个导出一个默认类或事物 即在foo ts export default class Foo
  • 使用“class-validator”在 TypeScript 中确认密码

    今天 我试图弄清楚如何在应用程序的后端 NestJS 验证注册表单 我只是想知道是否存在一种验证方法password and passwordConfirm匹配 使用class validator包来构建自定义验证器或利用提供的验证器 我正
  • 字符串类型中不​​存在属性 id

    我的 IDE 中出现以下错误 Property id does not exist on type string typeScript对于这行代码 if customer id id doesn t like customer id ret
  • Angular 中的单元测试点击事件

    我正在尝试将单元测试添加到我的 Angular 2 应用程序中 在我的一个组件中 有一个带有 click 处理程序 当用户单击按钮时 将调用在中定义的函数 ts类文件 该函数在 console log 窗口中打印一条消息 表明该按钮已被按下
  • 如何获取从类实例克隆的对象的类型?

    假设我有这个示例类 但实际上它有更多属性 class Foo name string dob number constructor name string dob number this name name this dob dob get
  • 考虑使用“jsdom”测试环境

    我有这个简单的测试 import React from react import render from testing library react import Button from describe Button gt it rend
  • 使用函数重载进行解构

    我正在尝试创建一个函数 该函数需要一对坐标或一个对象x and y属性并返回邻居列表 但由于某种原因 即使我检查了它的类型 我也无法解构该对象 interface Coords x number y number public getNei
  • 从 Angular 6 中的 html 导出 Pdf

    我想从 Angular 6 中的 html 导出 pdf 所以 我正在使用jspdf图书馆 但我不能给出颜色和背景颜色等样式 我怎样才能实现这个目标 如果有其他免费图书馆jspdf 我可以用它 您可以从下面的链接查看演示 DEMO http
  • 如何在 TypeScript 中使用 navigation.replace ?

    我试图在我的代码中使用它 const navigation useNavigation navigation replace AllFriends 但我不断收到错误消息 Property replace does not exist on
  • Angular 4 中的箭头函数(Lambda 函数)

    我对lambda知之甚少 lambda表达式被视为一个函数 我们有很多方法可以做到这一点 这是我的简单功能TypeScript file byPan card1 card2 return card1 pan card2 pan 我在 HTM

随机推荐