无法使用TypeScript从Array.find()强制转换参数的类型

gkl3eglg  于 2023-01-18  发布在  TypeScript
关注(0)|答案(1)|浏览(158)

我有以下OrganisationInterface类型:

export declare interface OrganisationInterface {
    documents?: {
        [documentType: OrganisationDocumentTypesList]: { // enum
            id: string;
            name: string;
            src?: string;
        }
    };
}

在我的可执行代码中,我有以下代码:

const organisation = { ...<OrganisationInterface>organisationSnap.data(), id: organisationId }

// Attempt 1 - Have typescript infer the type of 'record' variable
// TS throws error: 'record' is of type 'unknown'
const documentRecord = Object.values(organisation?.documents ?? {}).find((record) => record.id! === fileId)

// Attempt 2 - Cast 'record'
// TS throws error: No overload matches this call
const documentRecord = Object.values(organisation?.documents ?? {}).find((<OrganisationInterface['documents']>record) => record.id! === fileId)

// Attempt 3 - Cast 'record' variable on right side of 'find' method
// TS throws error - 'documents' is possibly undefined
const documentRecord = Object.values(organisation?.documents ?? {}).find((record) => (<OrganisationInterface['documents']>record).id! === fileId)

// Attempt 4 - Change 'documents' subobject from optional to required
// TS throws error - Property 'id' does not exist on type '{}'
const documentRecord = Object.values(organisation?.documents ?? {}).find((record) => (<Required<OrganisationInterface>['documents']>record).id! === fileId)

为什么TS拒绝让我分配通过Array.find()函数返回的record变量的类型?

idfiyjo8

idfiyjo81#

当你看到Object.values的定义时:values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];您可以看到类型是推断的。
可以为索引类型设置别名:

type Values<T> = T[keyof T];
type Document = Values<NonNullable<OrganisationInterface['documents']>>

那么你可以传递这个返回类型:

const documentRecord = Object.values<MyDocument>(organisation?.documents ?? {}).find((record) => record?.id === fileId)

Playground

相关问题