I've written a fairly complex definition file to match the behavior of an existing JavaScript library
export declare interface XcodeBaseFileTreeObject {
path: string;
includeInIndex?: 0 | 1;
usesTabs?: 0 | 1;
indentWidth?: number;
tabWidth?: number;
wrapsLines?: 0 | 1;
}
export declare interface XcodeUngroupedFileTreeObject extends XcodeBaseFileTreeObject {
sourceTree: `"<absolute>"` | "SOURCE_ROOT" | "DEVELOPER_DIR" | "BUILT_PRODUCTS_DIR" | "SDKROOT";
name: string;
}
export declare interface XcodeGroupedFileTreeObject extends XcodeBaseFileTreeObject {
sourceTree: `"<group>"`;
}
export declare type XcodeAbstractFileTreeObject = XcodeGroupedFileTreeObject | XcodeUngroupedFileTreeObject;
export declare type PBXBaseFileReference = XcodeAbstractFileTreeObject & {
readonly isa: "PBXFileReference";
fileEncoding?: 4 | 10;
lineEnding?: 0 | 1 | 2;
languageSpecificationIdentifier?: string;
xcLanguageSpecificationIdentifier?: string;
plistStructureDefinitionIdentifier?: string;
};
export declare type XcodeFileType = "archive.ar" | "archive.asdictionary" | "archive.binhex";
export declare type PBXInferredFileReference = PBXBaseFileReference & {
lastKnownFileType: XcodeFileType;
};
export declare type PBXExplicitFileReference = PBXBaseFileReference & {
explicitFileType: XcodeFileType;
};
export declare type PBXFileReference = PBXInferredFileReference | PBXExplicitFileReference;
Some union types as properties have been shortened for brevity, but the gist here is that I have a discriminating union from which another type is meant to inherit from, and in turn, another discriminating union is meant to inherit from that type. When I use the union at the bottom of the tree in a function like this:
function getFileType(file: PBXFileReference): XcodeFileType {
return file.lastKnownFileType ?? file.explicitFileType;
}
I get an error that neither lastKnownFileType
nor explicitFileType
exist on PBXFileReference
. In fact, neither property even comes up in the autocomplete when I'm writing that. I was expecting that to act as a typical discriminating union, where if one of those values isn't defined, it falls back on the other one definitely existing. How can I achieve the structure I'm looking for?
CodePudding user response:
You can use a ternary expression and use in
to check for the property before accessing it:
function getFileType(file: PBXFileReference): XcodeFileType {
return 'lastKnownFileType' in file ? file.lastKnownFileType : file.explicitFileType;
}