如果两种类型不匹配,我想得到一个错误。 我有一个对象:
const ACTIVITY_ATTRIBUTES = {
onsite: {
id: "applied",
....
},
online: {
id: "applied_online",
....
},
...
} as const
我希望限于服务器可以接受的字符串
export type ContactAttribute = "applied" | "applied_online" | "donated" | "messaged" | "reviewed"
我知道const不能带有类型限制(因为const将被忽略)。但是,有没有一种方法可以检查类型是否相等,以强制id属性为ContactAttribute类型?像这样:
$Values<typeof ACTIVITY_ATTRIBUTES >["id"] === ContactAttribute
答案 0 :(得分:2)
您应该查看此StackOverflow thread,以了解实现此目的的简便方法。
类似的东西:
const ACTIVITY_ATTRIBUTES = {
onsite: {
id: "applied",
},
donation: {
id: "donated",
},
online: {
id: "applied_online",
},
reviewe: {
id: "reviewed",
},
}
export type ContactAttribute = "applied" | "applied_online" | "donated" | "messaged" | "reviewed"
function isOfTypeContact (inputId: string): inputId is ContactAttribute {
return ["applied", "applied_online", "donated", "messaged", "reviewed"].includes(inputId);
}
console.log(isOfTypeContact(ACTIVITY_ATTRIBUTES.onsite.id)) // true
应该工作。
答案 1 :(得分:1)
我想出了一个辅助函数,该函数仅接受其属性具有类型id
的{{1}}属性的参数,并返回其原始参数,并且不更改其类型:
ContactAttribte
然后您将像这样创建const hasGoodContactAttributes =
<T extends Record<keyof T, { id: ContactAttribute }>>(t: T) => t;
:
ACTIVITY_ATTRIBUTES
如果您犯了一个错误,您将得到一个错误:
const ACTIVITY_ATTRIBUTES = hasGoodContactAttributes({
onsite: {
id: "applied",
otherProp: 123,
},
donation: {
id: "donated",
alsoOtherProp: 456
//....
},
online: {
id: "applied_online",
//....
},
reviewe: {
id: "reviewed",
//....
},
}); // as const if you want
好的,希望能有所帮助;祝你好运!
答案 2 :(得分:0)
您实际上可以通过使用以下代码来实现:
const ACTIVITY_ATTRIBUTES: {[key: string]: {id: ContactAttribute}} = {
onsite: {
id: "applied",
},
donation: {
id: "donated",
},
online: {
id: "applied_online",
},
reviewe: {
id: "reviewed",
},
hi: {
id: 'applied',
}
} as const
type ContactAttribute = "applied" | "applied_online" | "donated" | "messaged" | "reviewed"
但是,我怀疑这可能需要更多的类型检查,因为使用上述解决方案,即使id
都可以正确检查,您仍然可以为不同的id
放置虚假属性。
为避免此问题,您可能要使用discriminated union。
例如:
type Contact = {
id: "applied",
x: string
} | {
id: "applied_online"
y: number
}
利用此功能,可以确保与每个ContactAttribute
关联的预期属性将被正确初始化。
答案 3 :(得分:0)
这可以通过使用虚拟验证功能来实现。
const validateType = <T> (obj:T) => undefined
剩下的就是用类型和对象来调用它:
type ContactAttribute = "applied" | "applied_online" | "donated" | "messaged" | "reviewed"
type ActivityAttributes= {
[k:string]: {
id: ContactAttribute
}
}
const ACTIVITY_ATTRIBUTES = {
onsite: {
id: "applied",
....
},
donation: {
id: "donated",
....
},
...
} as const
validateType<ActivityAttributes>(ACTIVITY_ATTRIBUTES) // Will show an error if types don't match.
答案 4 :(得分:0)
您可以通过结合使用 declare
和死代码来实现这一点。 declare
语句纯粹是编译时,所以我们使用它们来设置我们类型的假“值”。然后我们使用一个死代码块来调用一个接受两个相同类型参数的函数。
type T1 = number;
type T2 = string;
declare const dummy1: T1;
declare const dummy2: T2;
declare function sameType<T>(v1: T, v2: T): void;
if (false) {
// @ts-ignore: Unreachable code
sameType(
// prevent line break so that the ts-ignore is only applied to the above line
dummy1, dummy2);
}
@ts-ignore
用于消除无法访问的代码错误。
我在 (
之后添加了一行注释,以防止 prettier 之类的工具将参数放在同一行,这会消除您想要实现的错误。
您也可以使用 as
表达式,它可能更简洁一些。
type T1 = number;
type T2 = string;
declare const dummy1: T1;
if (false) {
// @ts-ignore: Unreachable code
dummy1
// prevent line break so that the ts-ignore is only applied to the above line
as T2
}