TSA small note

Starting with TypeScript documentation, I still don’t understand a lot.

For example, common types of various frameworks, common types built into TS, as well as some easily overlooked and forgotten points, have been written down in this article.

TS

Easy to ignore keywords

keyof

The keyof operator takes an object type and produces a string or numeric literal union of its keys

The keyof operator returns the keyof an object type (note that this is a type, not a value) as a union type.

interface IProps {
  name: string;
  count: number;
}
type Ikea = keyof IProps; // Ikea = 'name' | 'count'

function testKeyof(props: Ikea) :void {}Copy the code

extends

define

Extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends extends

When the extends keyword represents a constraint, it means an attribute that requires a constraint to be implemented (included) on the generic.

Demo

Such as

function loggingIdentity<T> (arg: T) :T {
  console.log(arg.length) // Ts syntax error T can be of any type and does not have the length attribute
  return arg
}
Copy the code

We define an interface to describe the constraint, create an interface with the.length attribute, and use this interface and the extends keyword to implement the constraint:

interface Lengthwise {
  length: number
}

// indicates that the passed generic T is subject to the Lengthwise constraint
// T must implement Lengthwise. In other words, the Lengthwise type can be assigned to T
function loggingIdentity<T extends Lengthwise> (arg: T) :T {
  console.log(arg.length) // OK
  return arg
}
Copy the code

Now the generic function is constrained, so it no longer applies to any type:

loggingIdentity(3);  // Error
Copy the code

We need to pass in values that match the constraint type and must contain the required attributes:

loggingIdentity({length: 10, value: 3}) // OK
Copy the code
The commonly used

You can declare one type parameter and it is bound by another type parameter. For example, now we want to get the property from the object using the property name. And we want to make sure that this property exists on the object obj, so we need to use constraints between the two types.

function getProperty<T.K extends keyof T> (obj: T, key: K ) {
  return obj[key]
}

let x = {a: 1.b: 2.c: 3.d: 4}

getProperty(x, 'a') // okay
getProperty(x, 'm') // error
Copy the code

Represents two parameters passed in. The second parameter is constrained to be a key type that can only be passed in obj.

Built-in types

ReturnType<Type>

define

Constructs a type consisting of the return type of function Type.

ResultType

accepts a function whose type is generic and whose return value is the return type of the function.

Demo
type T0 = ReturnType<() = > string>; // type T0 = string

type T1 = ReturnType<(s: string) = > void>; // type T1 = void

Copy the code

Looking at the type definitions in the ReturnType source code, the Infer type definition is used.

infer

define

Infer represents the type variables to be inferred in the extends condition statement, which must occur in conjunction with the extends type.

demo

type ParamType<T> = T extends(... args: infer P) =>any ? P : T;


interface User {
  name: string;
  age: number;
}

type Func = (user: User) = > void;

type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string
Copy the code

The infer keyword can be understood simply as a type of infer (which I don’t know now, extends).

The point is:

  1. inferfollowextendsShow up in pairs.
  2. infer PAccording to the typePIs a type to be inferred. (don’t useinferdirectlyPComplains)

React & TSBuilt-in types

React.ReactNode

The ReactNode type definition in the source type

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Copy the code

As you can see, ReactNode is a type alias that is a combination of multiple types.

Which is suitable for the type ReactChild ReactChild = ReactElement | ReactText;

ReactPortal definition

 interface ReactPortal extends ReactElement {
        key: Key | null;
        children: ReactNode;
 }
Copy the code

So ReactNode is a union type that contains the ReactElement type. In other words, ReactElement can be assigned to a ReactNode, but not the other way around.

React.element

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }
Copy the code

You can see that the React.Element type accepts two generics passed in: the props and component of the JSX compiled VDOM object.

Returns only an Object containing type,props, and key.