keyof with number

We can also use the keyof keyword when working with numeric properties of an object. Remember that if we define an object with a numeric property, then we need to both define the property and access the property using array syntax as follows:

class ClassWithNumericProperty { 
    [1] : string = "one"; 
} 
let classWithNumeric = new ClassWithNumericProperty(); 
console.log(`${classWithNumeric[1]} `); 

Here, we have defined a class named ClassWithNumericProperty that defines a property named 1 to be of type string, and a value of "one". Note how we need to define this property using array syntax by defining it as [1], instead of just 1. We then create a class named classWithNumeric, and log the value of the property [1] to the console. The output of this code is simply:

one

What this shows us is that we are able to use property names that are numeric, if we use array syntax.

With this in mind, let's write some code that will return a string value for an enum type. Consider the following code:

enum Currency { 
    AUD = 36, 
    PLN = 985, 
    USD = 840 
} 
 
const CurrencyName = { 
    [Currency.AUD]: "Australian Dollar", 
    [Currency.PLN]: "Zloty" 
}

Here, we have defined an enum named Currency, and specified that the value of these enums are their corresponding international currency codes. We then define a constant named CurrencyName that is defining a string value for each of the enum values. We can therefore find a string value for the Australian Dollar enum value in two ways, as follows:

console.log(`CurrencyName[Currency.AUD] =  
    ${CurrencyName[Currency.AUD]}`); 
console.log(`CurrencyName[36] = ${CurrencyName[36]}`); 

Here, we are finding the string value for the Australian Dollar by referencing the corresponding numeric property, either CurrencyName[Currency.AUD], or simply CurrencyName[36].

We can then use the keyof keyword to generate a numeric literal for the numeric properties of the CurrencyName object, as follows:

function getCurrencyName<T, K extends keyof T> 
    (key: K, map: T): T[K] { 
    return map[key]; 
} 

Here, we have defined a function called getCurrencyName, which utilizes generic syntax, and defines a generic type named T, as well as a generic type named K. The key part of this code snippet is the type K extends keyof T. In other words, K must be a numeric literal that is derived from the numeric properties of T. This function has two parameters, named key (for the type of K) and map (for the type of T). Note that it is returning T[K], which means that it is returning a property named K from the type of T. The implementation of this function is really simple in that it is returning map[key], so it is returning the numeric property named [key] from the object named map. The interesting aspect is how we use this function, as follows:

let name = getCurrencyName(Currency.AUD, CurrencyName); 
console.log(`name = ${name}`); 
name = getCurrencyName(Currency.PLN, CurrencyName); 
console.log(`name = ${name}`); 

Here, we are defining a variable named name, which is the result of calling the getCurrencyName function. This call uses two arguments. The first is a value from our CurrencyEnum, and the second is the CurrencyName object itself. The output of this code is as follows:

name = Australian Dollar
name = Zloty

In the first call to the getCurrencyName function, we are specifying the enum value of Currency.AUD as our first argument, which is the type K. We are then specifying the object CurrencyName as our second argument, which is of type T. According to the function definition, K must extend keyof T. As CurrencyName[36], or CurrencyName[Currency.AUD] is a property of the object CurrencyName, we are satisfying these rules. If, however, we try to reference a numeric property that does not exist on the object CurrencyNameas follows:

name = getCurrencyName(Currency.USD, CurrencyName); 

The TypeScript compiler will generate the following message:

error TS2345: Argument of type 'Currency.USD' is not assignable to parameter of type 'Currency.AUD | Currency.PLN'.

This error is indicating that there is no property named Currency.USD of the object CurrencyName, since the keyof keyword generates a numeric literal of Currency.AUD | Currency.PLN for the type of T. So our type K, therefore, does not extend keyof T, hence the error.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.185.147