typescript 从具有布尔类型属性的对象构建Type?

plicqrtu  于 2023-06-07  发布在  TypeScript
关注(0)|答案(1)|浏览(168)

我想从这个对象构造一个类型:

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的键,你能帮助我或给予我任何建议吗?
谢谢

vcudknz3

vcudknz31#

作为第一步,我们必须删除isSynchronized上的类型注解;我们需要编译器推断出它的类型,然后使用推断出的类型来计算你要找的键集。您可以使用satisfies运算符来确保检查属性类型并将其约束为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中所要求的和在In TypeScript, how to get the keys of an object type whose values are of a given type?中所讨论的。其思想是KeysMatching<T, V>将计算为T的属性键的并集,其中这些键处的属性值可分配给V。具体来说,看起来你需要KeysMatching<IsSynchronized, true>
该语言没有提供原生的KeysMatching,但是有很多方法可以自己实现它,但有各种各样的问题和边缘情况。一种方法是 * 分布式对象类型 *,其中我们map overT的所有属性,然后index into所有键的结果,以计算出的属性类型的并集结束。像这样:

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];

Playground链接到代码

相关问题