Evaluate TypeScript method against the interface, for example T['methodName']

Suppose we have an interface:

class A {
   method(x:number) : string
}

And a function:

const b = (x: string) : number;

Our goal is to test the function against the interface.

Here is one way to achieve this:

type InterfaceKey = {
    method: any
};

function typecheck<T, K extends keyof InterfaceKey >(imp: () => T, d: T[K]) {
 //                                   K cannot be used to index type T ^
    imp();
    return d;
}

typecheck(someclass, 555); // <-- type check _is actually works_ here

// or

function typecheck <T>(imp: () => T, d: any) {
    imp();
    if(!d) {
        let mock: T;
        mock.default = d; // default does not exists on type T 
        return mock;
    }
    return d;
}

It seems that the first approach is the most effective, as it performs a type check in Webstorm (but not in tsc) although it does not compile.

For more information, check out: https://github.com/Microsoft/TypeScript/issues/15768

Answer №1

Are we headed in the right path?

class anotherClass {
  mymethod(y: number): string { return null!; };
}

const c = (y: number): string => null!;

type KeyInterface = {
  mymethod: any
};

function verifyType<U extends KeyInterface>() {
  return <V extends keyof KeyInterface>(e: U[V]) => {};
}

// should generate error if the signature of anotherClass's `mymethod` doesn't match that of `c`
verifyType<anotherClass>()(c);

Answer №2

//base interface
interface MyInterface {
    method: any 
}

// defining a check interface with specified method
interface CheckData<T extends MyInterface> {
    all(keys: {[P in keyof T]?: T[P]}): Check<T>;

    onlyMethod<Ts extends {[K in keyof Ts]: Ts[K]} & T>(fn: Ts['method']): Check<T>;
}

// check without specified method
interface Check<T> {
    all(keys: {[P in keyof T]?: T[P]}): Check<T>;
}

type CustomCheckData<T extends MyInterface > = CheckData<T>;
type CustomCheck<T> = Check<T>;

// a magic function to uncast type
function uncast(a: any): any{
    return <any>a;
}

// function overloading with generic parameters
function load<K extends MyInterface>(a: K): CustomCheckData<K>;
function load<T>(a: T): CustomCheck<T>;

// type guards for function overloading
function load<T, K extends MyInterface>(a: T|K): CustomCheckData<K> | CustomCheck<T>{
    if ((<K>a).method) return <CustomCheckData<K>>uncast(a);
    return <CustomCheck<T>> uncast(a);
}

// TEST

var C1 = {
    test: a => a + 1,
    method: a => 5
}

var C2 = {
    test: a => a + 1,    
}

let a1 = load(C1);
a1.all({ test: a => 1 });
a1.onlyMethod(55); // type error

let a2 = load(C2);
a2.all({ test: (a,b) => 1 }); // type error
a2.all({ test2: a => 1 });// type error
a2.onlyMethod(55); //no such method

It is evident that the outcome is clear and understandable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to retrieve a specific property from an array of objects in Angular 6 using typescript?

I am currently working on a budgeting application that incorporates an array of expenses with a price property. Each expense is defined within an Expense model in Typescript. While I can easily access the price property using ngFor loop in HTML, I'm c ...

Angular location services

I'm experiencing some difficulties with the geolocation feature. It works fine when the user clicks allow, but there's an issue when using If else. If the user clicks deny, it doesn't insert into the else block. You can check out this DEMO f ...

What is the reason that Jest is not able to spy on the function?

A custom Hook was developed with only one function being imported. Ensuring this function is called with the correct arguments is crucial. import { IsValueAlreadyRegistered } from "../../entities/registration/actions"; export const useForgetPass ...

Angular loop using an HTTP GET request is producing garbled information

Currently, I have a loop that includes an http GET request. This is the sample loop code: for (let index = 0; index < datas.length; index++) { let car = datas[index].smiles; console.log('or--> ' + car); this.subscr = this.CarServ ...

typescript Can you explain the significance of square brackets in an interface?

I came across this code snippet in vue at the following GitHub link declare const RefSymbol: unique symbol export declare const RawSymbol: unique symbol export interface Ref<T = any> { value: T [RefSymbol]: true } Can someone explain what Re ...

When multiple input fields with an iterative design are using the same onChange() function, the specific event.target.values for each input

I'm in the process of developing a dynamic select button that adjusts based on the information entered into the iterative input fields I've set up. These input fields all utilize the same onChange() function. for (let i = 0; i < selectCount; i ...

Unable to serve static files when using NextJs in conjunction with Storybook

The documentation for Next.js (found here) suggests placing image file paths under the public directory. I have a component that successfully displays an image in my Next.js project, but it doesn't render properly within Storybook. The image file is ...

Issue: Formcontrolname attribute is undefined causing TypeError when trying to retrieve 'get' property.Remember to define formcontrolname attribute to

Having trouble creating a form at the moment and keep encountering this error: 'ERROR TypeError: Cannot read property 'get' of undefined' Even after trying various solutions like using formControlName in brackets or accessing the va ...

How to verify in HTML with Angular whether a variable is undefined

When it comes to the book's ISBN, there are instances where it may not be defined. In those cases, a placeholder image will be loaded. src="http://covers.openlibrary.org/b/isbn/{{book.isbn[0]}}-L.jpg?default=false" ...

NestJS integration tests are failing due to an undefined Custom TypeORM Repository

I am currently facing a challenge while writing integration tests for my Nest.js application. The custom TypeORM repositories in my test context are being marked as undefined. This issue may be occurring because I am not utilizing @InjectRepository. Instea ...

Creating a realistic typewriter effect by incorporating Code Block as the input

I am looking to add a special touch to my website by showcasing a code segment with the Typewriter effect. I want this code block not only displayed but also "typed" out when the page loads. Unfortunately, I have been unable to find a suitable solution s ...

Utilizing a constant in setting the slotLabelFormat

I am attempting to configure the slotLabelFormat options in a React TypeScript project When I directly set slotLabelFormat={{ hour: "2-digit", minute: "2-digit", omitZeroMinute: false, meridiem: "short" }}, TypeScript compile ...

Yup will throw an error if both a minimum value is set and the field is also marked

I am attempting to validate my schema using yup: import * as yup from "yup"; let schema = yup.object().shape({ name: yup.string().min(5) }); const x = { name: "" }; // Check validity schema .validate(x, { abortEarly: false }) . ...

Data fetched using React Query

When using React Query to fetch data, the function runs smoothly. After console.logging the 'data' variable from React Query, it prints an array of objects as expected and handles states efficiently between loading, success, error. The issue ar ...

The For loop causing crashes in the Filter button functionality

I am currently working on implementing a buy it now only filter button for listings that allow that option. However, I am facing an issue where the app crashes when the button is clicked due to a for loop in my code. Strangely, if I remove the for loop, ...

Destructuring an array of strings for use as parameters

Hey guys, I'm working with an array of keys here Example 1: let keyArray = ['x', 'y', 'z'] I'm trying to find a way to use these keys as parameters without repeating them multiple times. Do you have any suggestions ...

Filtering database results from an Angular component

I am currently working on an Angular component and I have a result variable in the .ts file that stores data retrieved from the database. My goal is to filter this result variable to display only 20 records and sort them by date either in ascending or de ...

Suddenly encountered issue when working with TypeScript Interfaces while integrating Quicktype 'allOf'

Our transition from using JSON Type Definition to JSON Schema includes the utilization of Quicktype to convert JSON Schemas into TypeScript Types. While Quicktype has been effective in most cases, it seems to struggle with converting Discriminators and mor ...

Angular's mechanism for detecting changes in a callback function for updates

I have come across a puzzling scenario regarding a basic issue. The situation involves a simple component with a boolean property that is displayed in the template of the component. When I update this property within a callback function, the property is up ...

Extending Enums in Typescript: A Comprehensive Guide

How can you work with a list of constants or Enum? Here is an example: enum MyList { A, B } enum MyList2 { C } function process<T>(input:MyList | T):void { } process<MyList2>(123) // The compiler does not recognize that 123 ...