Preserve the type

Date: 09.02.2022

Typescript generic type variables preserve the captured type of the given value resulting in having the exact type of this value. The following examples examine the generic type variables usage in different ways.

First, let's see how the type is captured by simply assigning value to the constant and local variable.

Assigning

BigInt

/*
    BigInt
*/
// 1n
const age = 1n;

// bigint
let localAge = 1n;

// bigint
const moreAge: bigint = 2n;

// { age: bigint; }
const objectAge = { age: 1n };

// { age: bigint; }
const objectMoreAge = { age };

Number

/*
    Number
*/
// 27 
const someoneAge = 27;

// number[]
const ageInArray = [ 27 ];

// number[]
const someoneAgeInArray = [someoneAge];

// { age: number }
const ageInObject = { age: 27 };

// { someoneAge: number; }
const someoneAgeInObject = { someoneAge }

String

/*
    String
*/
// "Someone" 
const firstName = 'Someone';

// string[] 
const arrayOf = ['Someone'];

// { firstName: string; }
const objectSomeone = { firstName: 'Someone' };

// string[] 
const arrayOfString = [firstName];

// { firstName: string; }
const objectFirstName = { firstName };

Conclusion

The variable declared by the let statement does not capture any exact type, obviously because it can be changed and by const statement captures the exact type, because it cannot be changed.

We can see that the value type is not captured in the array or object, even though the value is constant, so let's see what the generic type variables can capture by using the function.

Capturing

Capture the number in the array or object.

Number

Successful capture from an array by using the function with the generic type variable Age.

// 27
const age = 27;

// Create function to capture the age in the array.
const captureAgeFromArray = <Age extends number>(age: Age[]) => {
  return age;
};

// (4 | 5)[]
captureAgeFromArray([4, 5]);

// (9 | 27)[]
captureAgeFromArray([9, age]);

Unsuccessful capture from an array by using the function with the generic type variable Age.

// 27
const age = 27;

// Create function to capture the age in the array.
const captureAgeFromArray = <Age extends number>(age: Age[]) => {
  return age;
};

// Define constant to provide to the function.
const fromArray = [4, 5];

// number[] <---- Not Captured.
captureAgeFromArray(fromArray);

// Define constant to provide to the function.
const fromArrayAge = [9, age];

// number[] <---- Not Captured.
captureAgeFromArray(fromArrayAge);

Successful capture from an object by using the function with the generic type variable Age.

// 27
const age = 27;

// Create function to capture the age in the object.
const captureAgeFromObject = <Age extends number>(age: { age: Age[] }) => {
    return age;
}

// { age: (4 | 5)[]; }
captureAgeFromObject({
    age: [4, 5]
});

// { age: (9 | 27)[]; }
captureAgeFromObject({
    age: [9, age]
});

Unsuccessful capture from an object by using the function with the generic type variable Age.

// 27
const age = 27;

// Create function to capture the age in the object.
const captureAgeFromObject = <Age extends number>(age: { age: Age[] }) => {
    return age;
}

// Define constant to provide to the function.
const fromObject = {
    age: [4, 5]
};

// { age: number[]; } <---- Not Captured.
captureAgeFromObject(fromObject);

// Define constant to provide to the function.
const fromObjectAge = {
    age: [9, age]
};

// { age: number[]; } <---- Not Captured.
captureAgeFromObject(fromObjectAge);

Conclusion

The function with the generic type variable can capture the parameter type of array or object directly inputted, but through constant does not work. The same refers to the class, getting the detailed/exact type of it.

Last updated

Was this helpful?