Question: How to determine if a tuple element is optional
I'm traversing an object type, and I've hit a bit of a road-bump whilst attempting to determine if a tuple's element type is optional.
For example, with a declaration like this:
type Color = "Red" | "Green" | "Blue";
export type Box = {
colors: [Color, Color?];
};
How can I identify the 2nd element type of [Color, Color?] is optional?
My current attempts have predominantly been focused on the Type<ts.TupleType>, the tuple's underlying type.compilerType, and the tuple elements from type.getTupleElements(), however, I've been unsuccessful.
Any help in finding the information would be greatly appreciated, and thank you for such a fantastic library. 🙏
I couldn't find a way either using only ts-morph and had to read into the underlyingcompilerType to achieve it:
function checkOptionalTupleElements(type: Type<ts.Type>) {
const stringifiedTupleIndexes = type.getTupleElements().map((_, index) => `${index}`)
const optionalIndexed = type.compilerType
.getProperties()
// `getProperties` will return properties such as `length`, we need remove properties that are not an tuple element index.
.filter((property) => stringifiedTupleIndexes.includes(property.escapedName as string))
.map((typeSymbol) => (typeSymbol.getFlags() & SymbolFlags.Optional) !== 0)
return optionalIndexed
}
// Create a new project
const project = new Project({ useInMemoryFileSystem: true })
const sourceFile = project.createSourceFile(
"test.ts",
`
type Tuple = [number, number?];
`
)
const typeAlias = sourceFile.getTypeAliasOrThrow("Tuple")
const type = typeAlias.getType()
const result = checkOptionalTupleElements(type)
console.log(result) // Output: [false, true]
It's not ideal, but may work for you?