Search code examples
typescript

Does TypeScript support some form of an AND operator for conditional types?


For example, take the type below:

type TKeysofFunctionsStartingWithS<T, S extends string> = {
        [K in keyof T]: T[K] extends Function
            ? K extends `${S}${string}`
                ? K
                : never
            : never;
}[keyof T];

Does TypeScript support some form of an AND operator that would allow for something like this:

type TKeysofFunctionsStartingWithS<T, S extends string> = {
    [K in keyof T]: T[K] extends Function && K extends `${S}${string}`
        ? K
        : never
}[keyof T];

Solution

  • There is no such operator. A conditional type is a single syntactic thing that looks like ⋯ extends ⋯ ? ⋯ : ⋯. It's a quaternary operator (and not a ternary operator like the JavaScript conditional operator). You can't abstract over the part to the left of the question mark.

    If you want this behavior you can take advantage of the fact that types are considered covariant in their properties (see Difference between Variance, Covariance, Contravariance, Bivariance and Invariance in TypeScript) and so if you want to check that both T extends X and that U extends Y, you can package both into properties of an object type, like {a: T, b: U} extends {a: X, b: Y}. The tersest way to do that is to package the types into tuple types, like [T, U] extends [X, Y]:

    type TKeysofFunctionsStartingWithS<T, S extends string> = {
      [K in keyof T]: [T[K], K] extends [Function, `${S}${string}`] ? K : never
    }[keyof T];
    

    Playground link to code