10

https://blogs.msdn.microsoft.com/typescript/2018/07/12/announcing-typescript-3-0-rc/#the-unknown-type

TypeScript 3.0 introduces a new type called unknown that does exactly that. Much like any, any value is assignable to unknown; however, unlike any, you cannot access any properties on values with the type unknown, nor can you call/construct them. Furthermore, values of type unknown can only be assigned to unknown or any.

As an example, swapping the above example to use unknown instead of any forces turns all usages of foo into an error:

let foo: unknown = 10;

// Since `foo` has type `unknown`, TypeScript
// errors on each of these usages.
foo.x.prop;
foo.y.prop;
foo.z.prop;
foo();
new foo();
upperCase(foo);
foo `hello world!`;

function upperCase(x: string) {
    return x.toUpperCase();
}

I recently started to code in TypeScript, and here is my questions:

1. It seems to me, unknown can be the complete alternative to any.

Of course, a code written in native JavaScript requires to use any type automatically in TypeScript, but when we start from scratch to code in pure TypeScript, is there any reason to employ any type instead of unknown from version 3.0?

2. What is the diffrence between unknown and generics?

For instance,

const A = <T>(value: T): T => value;
const A1 = (value: unknown) => value;

console.log(A<string>('Hello'), A<number>(100));



const B = <T, U>(t: T, u: U) => {
    console.log(t);
    console.log(u);
};
const B1 = (t: unknown, u: unknown) => {
    console.log(t);
    console.log(u);
};

B<string, number>('Hello', 100);
B<number, string>(100, 'Hello');

and suppose the arugument value: unknown is originally defintely typed, the type of the value is identified, so it seems to me there is no reason to pass T explicitly.

Thanks.

Community
  • 1
  • 1

1 Answers1

13

With regard to the first part of your question, I would probably use unknown instead of any in most circumstances, better have the explicit assertions where necessary to make the programmer aware that something is not necessarily safe. A big issue with any was people unknowingly assigned it to typed variables or parameters expecting errors :

function foo() :any { return 1;} 
let x:string = foo () ;
x.bold() // runtime error

With any the above code causes a runtime error

function foo() : unknown { return 1;} 
let x:string = foo () ; // compile time error we need to think about why we are doing this. 

With the code above we would have to use an explicit assertion to make it work, and think about why we are asserting the result of foo to be string

Maybe this answer with regard to the difference between the two helps as well

With regard to this beeing an alternative to generics, it's not. Firstly you should avoid specifying explicit type parameters, most of the time the compiler will infer them for you.

const A = <T>(value: T): T => value;
const A1 = (value: unknown) => value;

// redundant and a lot of typing 
console.log(A<string>('Hello'), A<number>(100));
// let the compiler do the work for us
console.log(A('Hello'), A(100)) 

The power of generics does not show up if you use the generic argument in just one position (ie for a single parameter or for the return value) but rather when you use it to specify the relation between two or more.

For instance your A example :

 A('').bold() // ok return is the same as the parameter type

 A1('').bold() //error return value is of type unknown

Or for B we can specify that the parameters must be of the same type

const B = <T>(t: T, u: T) => {
    console.log(t);
    console.log(u);
};
const B1 = (t: unknown, u: unknown) => {
    console.log(t);
    console.log(u);
};

B('Hello', 100); //compile time error 
B1(100, 'Hello'); //compiles

Also generic parameters can have extra constraints on them so not all types are valid for a given type parameter.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • 1
    Thank you very much for your concise information!. It's very helpful, and I understand. –  Jul 28 '18 at 21:56
  • 1
    Thanks to both of you. I wanted to understand the different between unknown and generics and this is the perfect explanation. – Jashwant Jun 12 '21 at 03:21