0

I would like to obtain the following behaviour without using a T as any:

interface Test<T> {
  sameField: string;
  test: T
  testFunction: (e: T) => void
}

const array: Array<Test</*something something*/_>> = [
  {
    sameField: "foo",
    test: 1,
    testFunction: (e) => {
      e.toExponential(2) // Should be Valid
      e.indexOf('e') // Should be Invalid
    }
  },
  {
    sameField: "bar",
    test: "baz",
    testFunction: (e) => {
      e.indexOf('e') // Is Valid
      e.toExponential(2) // Should be Invalid
    }
  }
]

The idea behind it is just a way of telling Typescript "let the array elements handle their typing themselves". Is it only possible to do in Typescript ?

1 Answer 1

1

TS is unable to infer e argument in such kind of data structure on his own.

You have several options here.

First

Define your test property upfront:

type Main = {
    foo: string;
    bar: number;
};

type Validator<T extends keyof Main> = {
    test: T;
    isValid: (value: Main[T]) => boolean;
};

type Values<T> = T[keyof T]

type MainValidationRule = Values<{
    [P in keyof Main]: {
        test: P;
        isValid: (value: Main[P]) => boolean;
    }
}>

const validators: Array<MainValidationRule> = [
    { test: 'foo', isValid: (value/* infered to stirng */) => true },
    { test: 'bar', isValid: (value/* infered to number */) => true }
]

Second

interface Test<T> {
    field: string;
    test: T
    fn: (e: T) => void
}

const builder = <Test, Field>(test: Test, field: Field, fn: (e: Test) => any) => ({
    field,
    test,
    fn
})

const array = [builder(2, 'hello', (e/**infered to number */) => 42)]

Here, in my blog, you can find more information about using and typing callbacks

There is one more way to do it:

interface Foo {
    sameField: "foo",
    test: 1,
    testFunction(e: this['test']): void
}

const x: Foo = {
    sameField: "foo",
    test: 1,
    testFunction(e) {
        e.toExponential(2) // ok
        e.indexOf('e') // error
    }
}

But as you might have noticed, you should declare your sameField and test upfront

There are more options to do it, but I believe it will be an overhead

Sign up to request clarification or add additional context in comments.

1 Comment

Sad to hear that there is no way to infer it this way. Solution 1 is sadly impossible in my case, there is way too much possibilities. Will try with functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.