gpt4 book ai didi

typescript - 如何在 TypeScript 中实现强类型 ID?

转载 作者:行者123 更新时间:2023-12-02 15:56:11 24 4
gpt4 key购买 nike

强类型 ID 会使将错误的 ID 作为参数传递给函数变得更加困难。例如。如果 getThingById(notAThing.id)Thing 具有相同类型的 NotAThing ,则 id 很容易犯错误。

这里先破解一下,但是最后 Id<TModel, TId> 都是 number ,所以没有达到目的。如何更改它以使最后两个函数调用失败?

type Thing = { id: Id<Thing> };
type NotAThing = { id: Id<NotAThing> };

type Id<TModel, TId = number> = TId;

const thing: Thing = {
id: 123,
};

const notAThing: NotAThing = {
id: 456,
};

function getThing(id: Id<File>) {
return "here's the thing";
}

function getNotAThing(id: Id<NotAThing>) {
return "here's the not a thing";
}


// This works.
getThing(thing.id);
getNotAThing(notAThing.id);


// How to make it not work (fail compilation) if you pass the "wrong type of id"?
getThing(notAThing.id);
getNotAThing(thing.id);

Ready to test in the Playground

最佳答案

这个概念叫做“不透明类型”。它是一种类似于现有类型(如字符串或数字)但不可互换的类型。

Drew Colthorp 在文章 Flavoring: Flexible Nominal Typing for TypeScript 中描述了一个很好的实现它使用 TypeScript 品牌但允许隐式转换。它看起来像这样:

interface Flavoring<FlavorT> {
_type?: FlavorT;
}
export type Flavor<T, FlavorT> = T & Flavoring<FlavorT>;

然后可以用作(文章中的示例):

type PersonId = Flavor<number, "Person">
type BlogPostId = Flavor<number, "BlogPost">

现在可以为这两者分配简单的数字,但不能在定义为 PersonIdBlogPostId 的变量之间交叉分配值:

let p: PersonId = 1;
let b: BlogPostId= 2;

p = b; //error
b = p; //error

Playground Link


通过最小的更改,可以更改问题中的代码以将 Id 类型定义为:

type Id<T> = Flavor<number, T>;

然后可以通过传递一个字符串来使用它:

type Thing = { id: Id<"Thing"> };
type NotAThing = { id: Id<"NotAThing"> };

现在使示例按预期运行:Playground Link

关于typescript - 如何在 TypeScript 中实现强类型 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71486513/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com