英文:
Building a Type from an object with properties of type Boolean?
问题
我想从这个对象构造一个类型:
const isSynchronized: Record<SynchronizableField, boolean> = {
/* synchronized */
surveyMacroEnvironments: true,
coordinateReferenceSystemCrs: true,
transactionType: true,
epsgTransformation: true,
startingAgreementDate: true,
expirationAgreementDate: true,
transactionTypeNotes: true,
surveyDataType: true,
/* not synchronized */
surveyName: false,
validationStateCd: false,
legacy: false,
notifyOnCreate: false,
notifyOnValidate: false,
finalReportLink: false,
// timestamp fields
creationDate: false,
lastUpdate: false,
// continent and country are handled differently
continent: false,
country: false,
};
类型需要只包含值为true的键,请问您能帮我或提供任何建议吗?
谢谢
英文:
I would like to construct a type from this object:
const isSynchronized: Record<SynchronizableField, boolean> = {
/* synchronized */
surveyMacroEnvironments: true,
coordinateReferenceSystemCrs: true,
transactionType: true,
epsgTransformation: true,
startingAgreementDate: true,
expirationAgreementDate: true,
transactionTypeNotes: true,
surveyDataType: true,
/* not synchronized */
surveyName: false,
validationStateCd: false,
legacy: false,
notifyOnCreate: false,
notifyOnValidate: false,
finalReportLink: false,
// timestamp fields
creationDate: false,
lastUpdate: false,
// continent and country are handled differently
continent: false,
country: false,
};
where the type needs to have only the keys with values equal to true, could you please help me or give me any suggestions?
Thanks
答案1
得分: 1
作为第一步,我们需要删除isSynchronized
上的type annotation; 我们需要编译器 推断 其类型,然后使用推断的类型来计算你正在寻找的键集。您可以使用the satisfies
operator来确保属性类型被检查并限制为boolean
:
const isSynchronized = {
surveyMacroEnvironments: true,
coordinateReferenceSystemCrs: true,
transactionType: true,
epsgTransformation: true,
startingAgreementDate: true,
// ✂ ⋯ ✂
lastUpdate: false,
continent: false,
country: false,
} satisfies Record<string, boolean>;
type IsSynchronized = typeof isSynchronized;
现在,您可以检查IsSynchronized
以获取所需的类型。
您正在寻找应用我称之为 KeysMatching<T, V>
的类型函数,如microsoft/TypeScript#48992 中所请求的,以及在https://stackoverflow.com/q/54520676/2887218 中讨论的。其思想是 KeysMatching<T, V>
将计算为T
的属性键的union,其中这些键的属性值可分配给V
。具体来说,看起来您想要的是 KeysMatching<IsSynchronized, true>
。
语言本身没有提供本机的 KeysMatching
,但有多种方法可以自己实现它,具有各种问题和边缘情况。一种方法是使用分布式对象类型,我们可以遍历T
的所有属性,然后索引到结果中的所有键,以得到计算的属性类型的union。就像这样:
type KeysMatching<T, V> =
{ [K in keyof T]: T[K] extends V ? K : never }[keyof T]
然后让我们使用它:
type SynchronizedKeys = KeysMatching<IsSynchronized, true>;
// type SynchronizedKeys = "surveyMacroEnvironments" | "coordinateReferenceSystemCrs" |
// "transactionType" | "epsgTransformation" | "startingAgreementDate" |
// "expirationAgreementDate" | "transactionTypeNotes" | "surveyDataType"
看起来不错。如果您不想保留 KeysMatching
,您可以内联定义以直接计算SynchronizedKeys
:
type SynchronizedKeys = {
[K in keyof IsSynchronized]: IsSynchronized[K] extends true ? K : never
}[keyof IsSynchronized];
英文:
As a first step we have to remove that type annotation on isSynchronized
; we need the compiler to infer its type and then use that inferred type to compute the key set you're looking for. You could use the satisfies
operator instead to make sure the property types are checked against and constrained to boolean
:
const isSynchronized = {
surveyMacroEnvironments: true,
coordinateReferenceSystemCrs: true,
transactionType: true,
epsgTransformation: true,
startingAgreementDate: true,
// ✂ ⋯ ✂
lastUpdate: false,
continent: false,
country: false,
} satisfies Record<string, boolean>;
type IsSynchronized = typeof isSynchronized;
Now you can inspect IsSynchronized
to get the desired type.
You're looking for an application of a type function I call KeysMatching<T, V>
, as requested in microsoft/TypeScript#48992 and as discussed in
https://stackoverflow.com/q/54520676/2887218. The idea is that KeysMatching<T, V>
would evaluate to the union of property keys of T
where the property values at those keys are assignable to V
. Specifically it looks like you want KeysMatching<IsSynchronized, true>
.
There's no native KeysMatching
provided by the language, but there are a number of ways to implement it yourself, with various issues and edge cases. One approach is a distributive object type where we map over all the properties of T
and then index into the result with all the keys to end up with the union of the computed property types. Like this:
type KeysMatching<T, V> =
{ [K in keyof T]: T[K] extends V ? K : never }[keyof T]
And let's use it:
type SynchronizedKeys = KeysMatching<IsSynchronized, true>;
// type SynchronizedKeys = "surveyMacroEnvironments" | "coordinateReferenceSystemCrs" |
// "transactionType" | "epsgTransformation" | "startingAgreementDate" |
// "expirationAgreementDate" | "transactionTypeNotes" | "surveyDataType"
Looks good. If you don't want to keep KeysMatching
around, you can inline the definition to compute SynchronizedKeys
directly:
type SynchronizedKeys = {
[K in keyof IsSynchronized]: IsSynchronized[K] extends true ? K : never
}[keyof IsSynchronized];
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论