简体   繁体   中英

How to get TypeScript to allow optional parameters?

The below code works as intended in JavaScript, but when compiling it to TypeScript I get the error

t.ts:11:34 - error TS2554: Expected 1 arguments, but got 6.    
11 console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 2))
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

t.ts:14:34 - error TS2554: Expected 1 arguments, but got 6.
14 console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 4))
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Question

How can I get this function to work in TypeScript?

 var obj = [{ "category1": { nested: { a: 'string', b: [69, 13, 15] } }, "category2": "2", }]; console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 2)) // print 15 console.log(where_undefined(obj, 0, 'category1', 'nested', 'b', 4)) // print undefined at key 4 function where_undefined(obj) { var args = Array.prototype.slice.call(arguments) args.shift(); while (args.length) { var arg = args.shift(); if (obj[arg] === undefined) { console.log("undefined at key " + arg); break; } else { obj = obj[arg]; } } return obj; }

First, like @A_A has described, we should be using rest parameters :

function where_undefined(obj: any, ...args: PropertyKey[]) {

We also need to give them types. I have used any for obj here, because if we had used unknown , we'd get many more unnecessary errors in the function body. PropertyKey is a built-in type that represents all possible types for keys ( string | number | symbol ).

Since we're using rest parameters, we don't need this bit:

var args = Array.prototype.slice.call(arguments)
args.shift();

All this is doing is getting the same result as args in our new code.

The next change is here:

const arg = args.shift()!;

We use ! to assert that this cannot be undefined (since undefined cannot be used as a key). If we did not use an assertion here, we'd get errors when we try to use arg as a key:

obj[arg] // ! Type 'undefined' cannot be used as an index type.

However, now when you give it an object, it always returns any , no matter what the type of the object was, so we'll go back and change any to use a generic:

function where_undefined<T>(obj: T, ...args: PropertyKey[]): T {

But with this change, we get even more errors in the body. We can "ignore" these by changing this to an external signature:

function where_undefined<T>(obj: T, ...args: PropertyKey[]): T {
function where_undefined(obj: any, ...args: PropertyKey[]) {

The final result can be seen in this playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM