镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Add .isApplicableIndexType() to the TypeChecker #61886

Description

🔍 Search Terms

"isApplicableIndexType", "TypeChecker"

✅ Viability Checklist

⭐ Suggestion

Please consider adding the .isApplicableIndexType() method to the TypeChecker.

📃 Motivating Example

Currently one can use .getStringIndexType() and .getNumberIndexType() available on the Type object. Those work fine, but do not include symbol and template string pattern index signatures that were introduced in TypeScript 4.4.

The change was made in #44512. The isApplicableIndexType() function was added in the PR, but it is not public. Here is how it looks:

function isApplicableIndexType(source: Type, target: Type): boolean {
    // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index
    // signature applies to types assignable to 'number', `${number}` and numeric string literal types.
    return isTypeAssignableTo(source, target) ||
        target === stringType && isTypeAssignableTo(source, numberType) ||
        target === numberType && (source === numericStringType || !!(source.flags & TypeFlags.StringLiteral) && isNumericLiteralName((source as StringLiteralType).value));
}

Simple enough, but not possible to reimplement, because of a tiny detail: numericStringType.

💻 Use Cases

  1. What do you want to use this for?

I pass typeChecker.getIndexInfosOfType(sourceType) and want to check, if the targetType has an applicable index signature:

typeChecker
  .getIndexInfosOfType(sourceType)
  .some(({ keyType }) => typeChecker.isApplicableIndexType(targetType, keyType));
  1. What shortcomings exist with current approaches?

.getStringIndexType() and .getNumberIndexType() are available, but as mentioned above they do not cover all the cases. .isApplicableIndexType() could cover these, but it is not public.

  1. What workarounds are you using in the meantime?

Currently I am applying a patch that exposes .isApplicableIndexType(). That cannot work in long term unfortunately.

Also I have noticed that .getStringIndexType() and .getNumberIndexType() do not exist anymore in TypeScript 7. Might be worth to remove or at least to deprecate them in Strada as well. An alternative? Obviously: .typeChecker.isApplicableIndexType().

Activity

  1. RyanCavanaugh commented on Jun 23, 2025

    @RyanCavanaugh
    Member

    I don't think we'll be further expanding the API surface since this is effectively a dead end with TS7 on the way. What's your use case for this?

  2. mrazauskas commented on Jun 24, 2025

    @mrazauskas
    ContributorAuthor

    The project I work on is using TypeScript’s programatic API. A user is providing a type and a key (string, number or symbol) and the logic checks whether the key exists in the type.

    Without .isApplicableIndexType() it is not possible to check index signatures with template literal string like: [key: `data-${string}`]. I mean, not possible to do that programatically. And it is not possible to reimplement .isApplicableIndexType() either because it uses private APIs, as mentioned above.


    I do agree that expanding the API surface is not always acceptable.

    As mentioned above, currently .getStringIndexType() and .getNumberIndexType() are available on Type object. They do not cover index signatures with template literal string. In other words, these are outdated APIs and could be removed in favour of .isApplicableIndexType(). Not the best argument, but in a way the API surface becomes smaller.

  3. RyanCavanaugh commented on Jun 24, 2025

    @RyanCavanaugh
    Member

    A user is providing a type and a key (string, number or symbol) and the logic checks whether the key exists in the type.

    I understand the mechanical thing that's happening but I don't understand the motivation here.

  4. mrazauskas commented on Jun 25, 2025

    @mrazauskas
    ContributorAuthor

    Thanks for your time and also for your work on TypeScript. That’s a great value for many people. I appreciate that!

    Meanwhile I came up with an alternative solution that works with older versions of TypeScript and does not require .isApplicableIndexType() as well.


    The use case is type testing.

    (There are few libraries that try to implement type testing via generic type manipulation. I do not think that is good idea. Type manipulation is not the same as testing. What is testing? That’s a good question, indeed.)

    The approach I am heading for: create a virtual file with erased syntax and type check it. I think that should work with any version of TypeScript.

    Here is a concrete example:

    import { expect } from "tstyche";
    
    const sample: { [key: number]: unknown } = {};
    
    expect(sample).type.toHaveProperty("123");
    expect(sample).type.toHaveProperty(123);
    expect(sample).type.not.toHaveProperty("foo");

    would be roughly turned into:

    const sample: { [key: number]: unknown } = {};
    
          (sample)                    ["123"];
          (sample)                    [123];
          (sample)                        ["foo"]; // error!

    and all I have to do is to report or silence the errors.

    By the way, I already implemented .toBeCallableWith() in a similar way.

  5. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions