Quirky happenings in Typescript

TS Playground

function foo(a: number, b: number) {
  return a + b;
}

type Foo1 = typeof foo extends (...args: unknown[]) => unknown ? true : false; // false
type Foo2 = typeof foo extends (...args: any[]) => unknown ? true : false; // true

What is the reason it functions correctly with any[], but not with unknown[]?

The behavior is successful with tuples and ReturnTypes, but not with rest parameters.

type Foo = ['bar', 'baz'] extends unknown[] ? true : false; // true

Answer №1

Update: Please refer to the comment on the original post for clarification, as the following response was provided based on inaccurate information I previously had about Typescript.


The reason for this issue is due to the constraints imposed by assigning a value to an unknown type. For instance, variables of the number data type can receive values from variables with the any type, but are unable to accept values from variables with the unknown type.

For instance:

let value:any = 5;
let value2:unknown = 6;

let b:number = value;
let c:number = value2;

In this scenario, variable b will compile successfully, while variable c will not, resulting in the error message "Type 'unknown' is not assignable to type 'number'."

Answer №2

Comparing functions in TypeScript can be unexpectedly complex and unintuitive, as highlighted in the specific section of the handbook addressing this topic.

The code example presented reveals a challenge related to function parameter bivariance. A workaround involves comparing the parameters and return type of one function with those of another function independently. Take a look at the following:

In response to your query, Tobias S. referenced another explanation elaborating on various types of variance.

TS Playground

type Fn<Params extends readonly any[] = readonly any[], Result = any> =
  (...params: Params) => Result;

type FnAExtendsFnB<FnA extends Fn, FnB extends Fn> =
  Parameters<FnA> extends Parameters<FnB>
    ? ReturnType<FnA> extends ReturnType<FnB>
      ? true
      : false
    : false;

type AExtendsB<A, B> = A extends B ? true : false;

// The function from your question:
type Foo = Fn<[a: number, b: number], number>;

type UnknownParamsUnknownResult = Fn<unknown[], unknown>;
type AnyParamsUnknownResult = Fn<any[], unknown>;

declare const T1: AExtendsB<Foo, UnknownParamsUnknownResult>; // false

declare const T2: AExtendsB<Foo, AnyParamsUnknownResult>; // true

declare const T3: FnAExtendsFnB<Foo, UnknownParamsUnknownResult>; // true

declare const T4: FnAExtendsFnB<Foo, UnknownParamsUnknownResult>; // true

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

Retrieving information selectively using useSWRImmutable

Having issues fetching data using useSWRImmutable. The problem arises when attempting to display the fetched data inside the UserRow component. Even though I can successfully print the data outside of the UserRow component, any console.log() statements wi ...

Ensuring that the field is empty is acceptable as long as the validators are configured to enforce

I have successfully created a form using control forms. idAnnuaire: new FormControl('',[Validators.minLength(6),Validators.maxLength(6)]), However, I am facing an issue where when the field is left empty, {{form.controls.idAnnuaire.valid }} is ...

RXJS - Hold off until the shop is fully stocked

Here's a function I have that needs some adjustment: combineLatest([this.contact$, this.account$]).pipe( map((res) => {contacts = res[0], account = res[1]})).subscribe() I am facing an issue where the contact$ selector is sometimes empty. If it ...

Handling Click and Mouse Events with React [react-sortable-hoc, material-ui, react-virtualized]

I have come across an interesting example that I would like to share with you. Check out this live working example on Stackblitz When the delete button on the red bin icon is pressed, the onClick event handler does not get triggered (sorting happens inst ...

The defaultValue of the Observable TextArea is blank space following the transmission of a sendMessage using SignalR in a Typescript

i am currently in the process of modifying a basic SignalR Chat feature. Here is the situation: when a user sends a message, the message gets sent successfully. However, the textarea from which it was sent remains filled with empty space (aside from the p ...

Creating a dynamic list in Typescript from a tuple array without any intersections

const colors = ["red", "blue", "green", "yellow"] as const; const buttonSizes = ["small", "medium", "large"] as const; type ColorType = (typeof colors)[number]; type SizeType = (typeof b ...

Angular - Dropdown menu fails to display options

I encountered an issue with the JSON response from my Angular-12 API endpoint: { "message": "vehicle Model Detail.", "error": false, "code": 200, "results": { "vehiclemakes": [{ ...

Compiling the configureStore method with the rootreducer results in compilation failure

Software Setup @angular/cli version: ^9.1.2 System Details NodeJS Version: 14.15.1 Typescript Version: 4.0.3 Angular Version: 10.1.6 @angular-redux/store version: ^11.0.0 @angular/cli version (if applicable): 10.1.5 OS: Windows 10 Expected Outcome: ...

What is the proper way to specify the type for a proxy that encapsulates a third-party class?

I have developed a unique approach to enhancing Firestore's Query class by implementing a Proxy wrapper. The role of my proxy is twofold: If a function is called on the proxy, which exists in the Query class, the proxy will direct that function call ...

What is the process for transforming binary code into a downloadable file format?

Upon receiving a binary response from the backend containing the filename and its corresponding download type, the following code snippet illustrates the data: 01 00 00 00 78 02 00 00 6c 02 00 00 91 16 a2 3d ....x...l....... 9d e3 a6 4d 8a 4b b4 38 77 bc b ...

Angular 2 Login Component Featuring Customizable Templates

Currently, I have set up an AppModule with a variety of components, including the AppComponent which serves as the template component with the router-outlet directive. I am looking to create an AuthModule that includes its own template AuthComponent situa ...

Limit input to numbers only in Semantic UI React Form Field

I've developed a custom CurrencyInput React component for users to input numeric values. I set the input type to "number", but unfortunately, this only seems to function properly in Chrome (as Firefox still allows non-numeric entries). Here is the co ...

Unable to grab hold of specific child element within parent DOM element

Important Note: Due to the complexity of the issue, the code has been abstracted for better readability Consider a parent component structure like this: <child-component></child-component> <button (click)="doSomeClick()"> Do Some Click ...

Issue locating name (generics) in Angular 4

I'm encountering issues with Angular 4. The TypeScript code is not compiling and generating errors when I try to run ng serve. I'm getting two errors in my-data.service.ts file - "Cannot find name 'Category' at line 9, column 30" and ...

What is the best way to perform a query in Angular using Firebase Firestore?

I am attempting to execute queries in Angular 6 using Firebase Firestore. I have this code, and I have already installed the package "npm firebase @angularfire" but it is not working: import { Component } from '@angular/core'; import { A ...

How can you line up various form elements, like pickers, in a row using Material UI?

As someone new to material ui, I haven't come across a solution for my specific issue yet. While there are similar questions, none seem to address the problem of aligning different form field types. My observation is that the material ui date picker ...

Displaying a TypeScript-enabled antd tree component in a React application does not show any information

I attempted to convert the Tree example from antd to utilize TypeScript, however, the child-render function does not seem to return anything. The commented row renders when I remove the comment. The RenderTreeNodes function is executed for each element in ...

Is there a way to retrieve a compilation of custom directives that have been implemented on the Vue 3 component?

Is there a way to retrieve the list of custom directives applied to a component? When using the getCurrentInstance method, the directives property is null for the current component. I was expecting to see 'highlight' listed. How can I access the ...

Unable to spy on the second and third call using Jest

I'm having trouble using spyOn on the second and third calls of a function in my jest test I attempted to follow the documentation with this approach: it("should succeed after retry on first attempt failure", async () => { jest.spyOn(n ...

Using setTimeout() and clearTimeout() alongside Promises in TypeScript with strict mode and all annotations included

Many examples of timer implementations using Promises in JavaScript seem overly complex to me. I believe a simpler approach could be taken. However, I am looking for a solution specifically tailored for TypeScript with the "strict": true setting and all ne ...