λ©΄μ± μ‘°ν :μ΄ λ¬Έμ λ νλ¦μ΄ TypeScriptλ³΄λ€ λ«κ±°λ λμλ€λ κ²μ μ¦λͺ νκΈ°μν κ²μ΄ μλλΌ λ νμ λλΌμ΄ μμ μ λΉννκ³ μΆμ§ μμ§λ§ Flowμ TypeScript μ ν μμ€ν μ μ°¨μ΄μ μ λμ΄νκ³ μ΄λ€ κΈ°λ₯μ νκ°νλ €κ³ ν©λλ€. TypeScriptλ₯Ό κ°μ ν μ μμ΅λλ€.
λν λͺ©μ μ΄ TypeScriptλ₯Ό κ°μ νκΈ° μν΄ λͺ
μλ κ²κ³Ό κ°κΈ° λλ¬Έμ Flowμμ λλ½ λ κΈ°λ₯μ λν΄μλ μΈκΈνμ§ μκ² μ΅λλ€.
λ§μ§λ§μΌλ‘μ΄ νλͺ©μ μ§μλλ es6 / es7 κΈ°λ₯μ΄ μλλΌ μ ν μμ€ν
μ κ΄ν κ²μ
λλ€.
mixed
λ° any
νλ¦ λ¬Έμμμ :
- νΌν© : λͺ¨λ μ νμ "μνΌ νμ ". λͺ¨λ μ νμ νΌν©μΌλ‘ νλ₯Ό μ μμ΅λλ€.
- any : "λμ "μ ν. λͺ¨λ μ νμ μμμ μ νμΌλ‘, κ·Έ λ°λμ κ²½μ°λ κ°λ₯ν©λλ€.
κΈ°λ³Έμ μΌλ‘ any
λ TypeScript any
μ λμΌνκ³ mixed
λ TypeScript {}
ν©λλ€.
Object
μ ννλ¦ λ¬Έμμμ :
μ΄λ€ κ²μ μ·¨ν μμλ μμΉμ μ£Όμμ λ¬λ €λ©΄ mixedλ₯Ό μ¬μ©νμμμ€. λμ Objectλ₯Ό μ¬μ©νμ§ λ§μμμ€! λͺ¨λ κ²μ νλμ κ°μ²΄λ‘ 보λ κ²μ νΌλμ€λ½κ³ , λ§μΌ λΉμ μ΄ "λͺ¨λ κ°μ²΄"λ₯Ό μλ―Ένλ€λ©΄, "λͺ¨λ κΈ°λ₯"μ μ§μ νλ λ°©λ²μ΄μλ κ²μ²λΌ κ·Έκ²μ μ§μ νλ λ μ’μ λ°©λ²μ΄ μμ΅λλ€.
TypeScriptλ₯Ό μ¬μ©νλ©΄ Object
λ {}
μ λμΌνλ©° λͺ¨λ μ νμ νμ©ν©λλ€. Flow Object
λ {}
νμ§λ§ mixed
μλ λ€λ¦
λλ€ string
, number
, boolean
λλ function
μ κ°μ λ€λ₯Έ κΈ°λ³Έ μ νμ νμ©νμ§ μμ).
function logObjectKeys(object: Object): void {
Object.keys(object).forEach(function (key) {
console.log(key);
});
}
logObjectKeys({ foo: 'bar' }); // valid with TypeScript and Flow
logObjectKeys(3); // valid with TypeScript, Error with flow
μ΄ μμμ λ³μ logObjectKeys
μ νμ νκ·Έκ° Object
μ μλΉ νμ΄ν λν {}
κ·Έλ¦¬κ³ μ μ¬ν λͺ¨λ μ ν λ°μλ€μ΄λλ‘ number
λ²μ§Έ ν΅νμ κ²½μ° logObjectKeys(3)
.
Flowλ₯Ό μ¬μ©νλ©΄ λ€λ₯Έ κΈ°λ³Έ μ νμ΄ Object
μ νΈνλμ§ μμΌλ―λ‘ μ ν κ²μ¬κΈ°κ° λ λ²μ§Έ νΈμΆ logObjectKeys(3)
μ€λ₯λ₯Όλ³΄κ³ ν©λλ€. _numberλ Object_μ νΈνλμ§ μμ΅λλ€.
νλ¦ λ¬Έμμμ :
JavaScriptμμ nullμ μμ μ μΌλ‘ λͺ¨λ κΈ°λ³Έ μ νμΌλ‘ λ³νλ©λλ€. λν λͺ¨λ κ°μ²΄ μ νμ μ ν¨ν κ±°μ£Όμμ λλ€.
λ°λλ‘ Flowλ nullμ λ€λ₯Έ μ νμ μΌλΆκ° μλ κ³ μ ν κ°μΌλ‘ κ°μ£Όν©λλ€.
νλ¦ λ¬Έμκ° κ½€ μμ νκΈ° λλ¬Έμμ΄ κΈ°λ₯μ μμΈν μ€λͺ νμ§λ μκ² μ΅λλ€. κ°λ°μκ° λͺ¨λ λ³μλ₯Ό μ΄κΈ°ννκ±°λ nullableλ‘ νμν΄μΌνλ€λ μ μ λͺ μ¬νμμμ€.
var test: string; // error undefined is not compatible with `string`
var test: ?string;
function getLength() {
return test.length // error Property length cannot be initialized possibly null or undefined value
}
κ·Έλ¬λ TypeScript μ ν λ³΄νΈ κΈ°λ₯κ³Ό λ§μ°¬κ°μ§λ‘ νλ¦μ nullμ΄ μλ κ²μ¬λ₯Ό μ΄ν΄ν©λλ€.
var test: ?string;
function getLength() {
if (test == null) {
return 0;
} else {
return test.length; // no error
}
}
function getLength2() {
if (test == null) {
test = '';
}
return test.length; // no error
}
Flow doc μΉμ
μ°Έμ‘°
ν΄λΉ TypeScript λ¬Έμ # 1256 μ°Έμ‘°
TypeScript νλ¦ μ§μ 곡μ©μ²΄ μ νκ³Ό λ§μ°¬κ°μ§λ‘ μ νμ κ²°ν©νλ μλ‘μ΄ λ°©λ² μΈ κ΅μ°¨ μ νλ μ§μν©λλ€.
κ°μ²΄λ₯Ό μ¬μ©νλ©΄ κ΅μ°¨ μ νμ λ―Ήμ€ μΈμ μ μΈνλ κ²κ³Ό κ°μ΅λλ€.
type A = { foo: string; };
type B = { bar : string; };
type AB = A & B;
ABμλ { foo: string; bar : string;}
μ νμ΄ μμ΅λλ€.
ν¨μμ κ²½μ° μ€λ²λ‘λλ₯Ό μ μΈνλ κ²κ³Ό κ°μ΅λλ€.
type A = () => void & (t: string) => void
var func : A;
λ€μκ³Ό κ°μ΅λλ€.
interface A {
(): void;
(t: string): void;
}
var func: A
λ€μ TypeScript μμ λ₯Ό κ³ λ €νμμμ€.
declare function promisify<A,B>(func: (a: A) => B): (a: A) => Promise<B>;
declare function identity<A>(a: A): A;
var promisifiedIdentity = promisify(identity);
TypeScriptλ₯Ό μ¬μ©νλ©΄ promisifiedIdentity
μ λ€μ μ νμ΄ μμ΅λλ€.
(a: {}) => Promise<{}>`.
νλ¦ promisifiedIdentity
μλ λ€μ μ νμ΄ μμ΅λλ€.
<A>(a: A) => Promise<A>
μΌλ°μ μΌλ‘ Flowλ TypeScriptλ³΄λ€ λ λ§μ μ νμ μΆλ‘ νλ €κ³ ν©λλ€.
μ΄ μλ₯Ό μ΄ν΄ λ³΄κ² μ΅λλ€.
function logLength(obj) {
console.log(obj.length);
}
logLength({length: 'hello'});
logLength([]);
logLength("hey");
logLength(3);
TypeScriptλ₯Ό μ¬μ©νλ©΄ μ€λ₯κ°λ³΄κ³ λμ§ μμ΅λλ€. νλ¦μμ logLength
μ λ§μ§λ§ νΈμΆμ number
μ length
μμ±μ΄ μκΈ° λλ¬Έμ μ€λ₯κ° λ°μν©λλ€.
λͺ μ μ μΌλ‘ λ³μλ₯Ό μ λ ₯νμ§ μλ ν νλ¦μ μ¬μ©νλ©΄μ΄ λ³μμ μ νμ΄μ΄ λ³μμ μ¬μ©μ λ°λΌ λ³κ²½λ©λλ€.
var x = "5"; // x is inferred as string
console.log(x.length); // ok x is a string and so has a length property
x = 5; // Inferred type is updated to `number`
x *= 5; // valid since x is now a number
μ΄ μμμ xλ μ²μμ string
μ νμ΄μ§λ§ λ²νΈμ ν λΉλλ©΄ μ νμ΄ number
λ‘ λ³κ²½λμμ΅λλ€.
λμ
νμ΄νλ‘ x = 5
λλ¬Έμ μλ¬ μ΄λ x
μ΄μ μ ν λΉ string
λ° μ ν λ³κ²½ν μ μλ€.
λ λ€λ₯Έ μ°¨μ΄μ μ Flowκ° νμ μ μΆλ₯Ό μλ°©ν₯μΌλ‘ μ ννμ¬ μ μΆ λ νμμ νμ 곡μ©μ²΄λ‘ νμ₯νλ€λ κ²μ λλ€. μ΄ μλ facebook / flow # 67 (λκΈ)μμ κ°μ Έμ¨ κ²μ λλ€.
class A { x: string; }
class B extends A { y: number; }
class C extends A { z: number; }
function foo() {
var a = new B();
if (true) a = new C(); // TypeScript reports an error, because a's type is already too narrow
a.x; // Flow reports no error, because a's type is correctly inferred to be B | C
}
( "μ¬λ°λ₯΄κ²"λ μλ³Έ κ²μλ¬Όμμ κ°μ Έμ¨ κ²μ
λλ€.)
νλ¦μ΄ a
λ³μκ° μ‘°κ±΄λ¬Έμ λ°λΌ B
μ ν λλ C
μ νμ κ°μ§ μ μμμ κ°μ§ νμΌλ―λ‘ μ΄μ B | C
μ μΆλ©λλ€. λ¬Έ a.x
λ κ°μ§ μ νμ΄ κ°μ§κ³ μκΈ° λλ¬Έμ μ€λ₯κ° λ°μνμ§ μμ΅λλ€ x
μ°λ¦¬κ° μ κ·Όμ μλνμ κ²½μ°, μμ±μ z
μμ±μ μ€λ₯κ° μ κΈ°λμμ κ²μ
λλ€.
μ΄κ²μ λ€μλ μ»΄νμΌλλ€λ κ²μ μλ―Έν©λλ€.
var x = "5"; // x is inferred as string
if ( true) { x = 5; } // Inferred type is updated to string | number
x.toString(); // Compiles
x += 5; // Compiles. Addition is defined for both string and number after all, although the result is very different
mixed
λ° any
μΉμ
μ μ
λ°μ΄νΈνμ΅λλ€. mixed
λ {}
μ λμΌνλ―λ‘ μλ₯Ό λ€μ΄ νμκ° μμ΅λλ€.Object
μ νμ λν μΉμ
μ΄ μΆκ°λμμ΅λλ€._ μμ κ²μ΄ μμΌλ©΄ μΈμ λ μ§ μλ € μ£Όμλ©΄ μ λ°μ΄νΈλ₯Όνκ² μ΅λλ€ ._
μ΄κ²μ ν₯λ―Έλ‘κ³ λ λ§μ ν λ‘ μμν μ’μ μΆλ°μ μ λλ€. λͺ νμ±μ μν΄ μλ³Έ κ²μλ¬Όμ λ³΅μ¬ νΈμ§μ λ³κ²½ν΄λ λ κΉμ?
Flowμ μμμΉ λͺ»ν μ¬ν (μΆκ° μ‘°μ¬μ λ°λΌμ΄ λκΈ μ λ°μ΄νΈ μμ )
μ΄μν ν¨μ μΈμ μ ν μΆλ‘ :
/** Inference of argument typing doesn't seem
to continue structurally? **/
function fn1(x) { return x * 4; }
fn1('hi'); // Error, expected
fn1(42); // OK
function fn2(x) { return x.length * 4; }
fn2('hi'); // OK
fn2({length: 3}); // OK
fn2({length: 'foo'}); // No error (??)
fn2(42); // Causes error to be reported at function definition, not call (??)
κ°μ²΄ 리ν°λ΄μμ μ ν μ μΆ μμ :
var a = { x: 4, y: 2 };
// No error (??)
if(a.z.w) { }
μ΄κ²μ ν₯λ―Έλ‘κ³ λ λ§μ ν λ‘ μμν μ’μ μΆλ°μ μ λλ€. λͺ νμ±μ μν΄ μλ³Έ κ²μλ¬Όμ λ³΅μ¬ νΈμ§μ λ³κ²½ν΄λ λ κΉμ?
λ΄κ° λ§ν κ²μ²λΌ λͺ©μ μ νλ¦ μ ν μμ€ν μ ν¬μνμ¬ μΌλΆ κΈ°λ₯μ΄ TypeScriptμ μ ν©ν μ§ νμΈνλ κ²μ λλ€.
@RyanCavanaugh λλ λ§μ§λ§ μλ₯Ό μΆμΈ‘νλ€.
var a = { x: 4, y: 2 };
// No error (??)
if(a.z.w) { }
Null νμΈ μκ³ λ¦¬μ¦κ³Ό κ΄λ ¨λ λ²κ·Έμ΄λ―λ‘λ³΄κ³ νκ² μ΅λλ€.
μ΄λ€
type A = () => void & (t: string) => void
var func : A;
μ ν΄λΉ
Declare A : () => void | (t: string) => void
var func : A;
μλλ©΄ κ·Έλ΄ μ μμ΅λκΉ?
@ Davidhanson90 μ λ§ μλλλ€ :
declare var func: ((t: number) => void) | ((t: string) => void)
func(3); //error
func('hello'); //error
μ΄ μμ μμ νλ¦μ ν΅ν© μ ν func
μμ μ΄λ€ μ νμΈμ§ μ μ μμΌλ―λ‘ λ κ²½μ° λͺ¨λ μ€λ₯λ₯Όλ³΄κ³ ν©λλ€.
declare var func: ((t: number) => void) & ((t: string) => void)
func(3); //no error
func('hello'); //no error
funcμλ λ μ νμ΄ λͺ¨λ μμΌλ―λ‘ λ νΈμΆμ΄ λͺ¨λ μ ν¨ν©λλ€.
TypeScriptμ {}
μ Flowμ mixed
μ¬μ΄μ λμ λλ μ°¨μ΄κ° μμ΅λκΉ?
@RyanCavanaugh λλ κ·Έκ²μ΄ μ¬μ ν κ·Έκ²μ λν΄ μκ°νλ κ²κ³Ό κ±°μ λμΌνλ€κ³ μκ°ν νμ μ λ§λ‘ λͺ¨λ₯Έλ€.
μ΄κ²μ μλͺ»λμμ΅λλ€.mixed
μλ μμ±μ΄ μμ΅λλ€. {}
Object.prototypeμμ μμ λ μμ±λ μμ΅λλ€. (# 1108)
λ λ€λ₯Έ μ°¨μ΄μ μ Flowκ° νμ μ μΆλ₯Ό μλ°©ν₯μΌλ‘ μ ννμ¬ μ μΆ λ νμμ νμ 곡μ©μ²΄λ‘ νμ₯νλ€λ κ²μ λλ€. μ΄ μλ https://github.com/facebook/flow/issues/67#issuecomment -64221511μμ κ°μ Έμ¨ κ²μ λλ€.
class A { x: string; }
class B extends A { y: number; }
class C extends A { z: number; }
function foo() {
var a = new B();
if (true) a = new C(); // TypeScript reports an error, because a's type is already too narrow
a.x; // Flow reports no error, because a's type is correctly inferred to be B | C
}
( "μ¬λ°λ₯΄κ²"λ μλ³Έ κ²μλ¬Όμμ κ°μ Έμ¨ κ²μ λλ€.)
μ΄κ²μ λ€μλ μ»΄νμΌλλ€λ κ²μ μλ―Έν©λλ€.
var x = "5"; // x is inferred as string
if ( true) { x = 5; } // Inferred type is updated to string | number
x.toString(); // Compiles
x += 5; // Compiles. Addition is defined for both string and number after all, although the result is very different
νΈμ§ : λ λ²μ§Έ μ€ λν«μ ν
μ€νΈνμΌλ©° μ€μ λ‘ μ»΄νμΌλ©λλ€.
νΈμ§ 2 : μλ @fdecampredonμμ μ§μ νλ―μ΄ λ λ²μ§Έ ν λΉ μ£Όλ³μ if (true) { }
λ Flowκ° μ νμ string | number
λ‘ μΆλ‘ νλλ‘ν΄μΌν©λλ€. if (true)
κ° μμΌλ©΄ λμ number
λ‘ μΆλ‘ λ©λλ€.
μ΄ νλμ΄ λ§μμ λμλκΉ? μ°λ¦¬λ μ λμ¨ μ νμ λν΄ λ Όμ ν λμ΄ κΈΈμ κ°κ³ κ·Έ κ°μΉλ λͺ¨νΈνμ΅λλ€. μ΄μ μ ν μμ€ν μ΄ μ¬λ¬ κ°λ₯ν μνλ‘ μ νμ λͺ¨λΈλ§ ν μ μλ€κ³ ν΄μ λͺ¨λ κ³³μμ μ¬μ©νλ κ²μ΄ λ°λμ§νλ€λ κ²μ μλ―Ένμ§λ μμ΅λλ€. νλ©΄μ μΌλ‘λ νμ μ΄λ Έν μ΄μ μμ±μ μ’μν΄μκ° μλλΌ μ€μ ν λ μ»΄νμΌλ¬ μ€λ₯λ₯Ό μνκΈ° λλ¬Έμ μ μ νμ κ²μ¬κΈ°κ°μλ μΈμ΄λ₯Ό μ¬μ©νκΈ°λ‘ μ ννμ΅λλ€.) μ¦, λλΆλΆμ μΈμ΄λ μ΄μ κ°μ μμ μμ μ€λ₯λ₯Ό λ°μμν΅λλ€ (νΉν λ λ²μ§Έ) μ ν 곡κ°μ λͺ¨λΈλ§νλ λ°©λ²μ΄ λΆμ‘±ν κ²μ΄ μλλΌ μ€μ λ‘ μ΄κ²μ΄ μ½λ© μ€λ₯λΌκ³ λ―ΏκΈ° λλ¬Έμ λλ€ (λΉμ·ν μ΄μ λ‘ λ§μ μμ μ μΊμ€νΈ / λ³ν μμ μ μ§μνλ λ§μ ννΌ).
λμΌν λ Όλ¦¬μ λ°λΌμ΄ λμμ κΈ°λν©λλ€.
declare function foo<T>(x:T, y: T): T;
var r = foo(1, "a"); // no problem, T is just string|number
νμ§λ§ μ λ κ·Έ νλμ μ λ§λ‘ μνμ§ μμ΅λλ€.
@danquirk μ€λ₯λ₯Όλ³΄κ³ νλ λμ μλμΌλ‘ ν΅ν© μ νμ μΆλ‘ νλ κ²μ λ΄κ° μ’μνλ νλμ΄ μλλΌλ μ μ λμν©λλ€.
κ·Έλ¬λ κ·Έκ²μ νλ¦ μ² νμμ λΉλ‘―λ κ²μ΄λΌκ³ μκ°ν©λλ€. μ€μ μΈμ΄κ° μλλΌ νλ¦ νμ λ¨μν μ ν κ²μ¬κΈ°λ₯Ό λ§λ€λ €κ³ ν©λλ€. κΆκ·Ήμ μΈ λͺ©νλ μ ν μ£Όμμμ΄ 'μμ ν'μ½λλ₯Ό λ§λ€ μμλ κ²μ
λλ€. μ΄κ²μ λ μ격νκ² μ΄μ΄μ§λλ€.
μ΄λ¬ν μ’
λ₯μ νλμ΄ λ―ΈμΉλ μν₯μ κ°μν λ μ νν μ격 μ±μ λ
Όμμ μ¬μ§κ° μμ΅λλ€. μ’
μ’
μ€λ₯λ₯Ό μ°κΈ°νκ±°λ μμ ν μ¨κΈ°λ κ²μ
λλ€. νμ
μΈμμ λν μ°λ¦¬μ μ€λλ νμ
μΆλ‘ κ·μΉμ λΉμ·ν μ² νμ λ§μ΄ λ°μνμ΅λλ€. μμ¬ μ€λ¬μΈ λ μ°λ¦¬λ μ ν λ§€κ° λ³μμ λν΄ {}λ₯Ό μ€λ₯λ‘ λ§λλ κ²μ΄ μλλΌ μΆλ‘ νμ΅λλ€. μ΄κ²μ λΉμ μ΄ μ½κ°μ μ΄λ¦¬μμ μΌμ ν μ μκ³ μ¬μ ν κ²°κ³Όμ λν΄ μ΅μνμ νλ μΈνΈλ₯Ό μμ νκ² ν μ μμμ μλ―Έν©λλ€ (μ¦, toString
κ°μ κ²λ€). μ΄λ€ μ¬λλ€μ JSμμ μ΄λ¦¬μμ μΌμνλ μ΄μ λ μ°λ¦¬κ° ν μμλ κ²μ νμ©νλ €κ³ λ
Έλ ₯ν΄μΌνλ€λ κ²μ
λλ€. κ·Έλ¬λ μ€μ λ‘ {}μ λν λλΆλΆμ μΆλ‘ μ μ€μ λ‘ μ€λ₯ μΌ λΏμ΄λ©° T
μ νμ λ³μλ₯Ό μ²μμΌλ‘ μ μΌλ‘ λΆλ¦¬νμ¬ {} (λλ λ§μ°¬κ°μ§λ‘ μκΈ°μΉ μμ 곡μ©μ²΄ μ ν)μμ μΈμ ν λκΉμ§ κΈ°λ€λ¦¬κ²ν©λλ€. κ·Έλ¦¬κ³ κ±°κΎΈλ‘ μΆμ νλ κ²μ κΈ°κ»ν΄μΌ μ±κ°μ μΌμ΄μμ΅λλ€. μ μ μ°μ§ μμ κ²½μ° (λλ T μ νμ νλͺ©μ λ°ννμ§ μμ κ²½μ°) λ°νμκΉμ§ μ€λ₯κ° λ°μνμ λ (λλ λ λμ κ²½μ°μλ λ°μ΄ν°κ° μμλ¨) μ€λ₯λ₯Ό μ ν μμ μ°¨λ¦¬μ§ λͺ»νμ΅λλ€. λΉμ·νκ²:
declare function foo(arg: number);
var x = "5";
x = 5;
foo(x); // error
μ¬κΈ°μ μ€λ₯κ° λ¬΄μμ
λκΉ? μ λ§ x
λ₯Ό foo
ν©λκΉ? μλλ©΄ μ΄κΈ°ν λ κ²κ³Ό μμ ν λ€λ₯Έ μ νμ κ°μ x
μ¬ν λΉνμ΅λκΉ? μ¬λλ€μ΄ μ€μ λ‘ μλμ μΌλ‘ κ·Έλ° μ’
λ₯μ μ¬ μ΄κΈ°νλ₯Όνλ κ²½μ°μ μ€μλ‘ λ¬΄μΈκ°λ₯Ό λ°λ κ²½μ°κ° μΌλ§λ μμ£Ό μμ΅λκΉ? μ΄μ¨λ x
λν 곡μ©μ²΄ μ νμ μΆλ‘ νμ¬ μ¬μ ν (λ λμ) μ€λ₯κ° λ°μνλ©΄ μ ν μμ€ν
μ΄ μ λ°μ μΌλ‘ λ μ격νλ€κ³ λ§ν μ μμ΅λκΉ? μ΄λ° μ’
λ₯μ μΆλ‘ μ μΌλ°μ μΌλ‘ λ§€μ° λλ¬Έ κ²°κ³Ό μ νμΌλ‘ νΉλ³ν μλ―Έμλ μμ
μ μννμ§ μλ κ²½μ°μλ§ λ μ격ν©λλ€.
νλ¦Όμμ΄ null
λ° undefined
λ₯Ό λμΌν λ°©μμΌλ‘ λͺ¨λ μ ν μ¨κΈ°κΈ° μ€λ₯μ ν λΉ ν μ μλλ‘ λ¨κ²¨λλ©΄ λλΆλΆμ κ²½μ° μΌλΆ μ νμΌλ‘ μ
λ ₯νκ³ null
κ°μ μ¨κΈ°λ λ³μλ λ°νμ μ€λ₯.
Flowμ λ§μΌν
μμ μ€μνμ§ μμ λΆλΆμ TSκ° any
μΆλ‘ νλ κ³³μμ μ ν κ²μ¬κΈ°κ° μ½λλ₯Ό λ μ μ΄ν΄νλ€λ μ¬μ€μ κΈ°λ°μΌλ‘ν©λλ€. κ·Έ μ² νμ μ»΄νμΌλ¬κ° μ νμ μΆλ‘ νλλ‘νκΈ° μν΄ μ£Όμμ μΆκ° ν νμκ° μλ€λ κ²μ
λλ€. μ΄κ²μ΄ κ·Έλ€μ μΆλ‘ λ€μ΄μΌμ΄ TypeScriptλ³΄λ€ ν¨μ¬ λ κ΄λ ν μ€μ μΌλ‘ λ°λλ μ΄μ μ
λλ€.
λκ΅°κ°κ° var x = new B(); x = new C();
(Bμ Cκ° λͺ¨λ Aμμ νμ λ¨)κ° μ»΄νμΌλμ΄μΌνλ€κ³ κΈ°λνλμ§ μ¬λΆμ λ¬λ € μμΌλ©°, λ§μ½ κ·Έλ λ€λ©΄ μ΄λ»κ² μΆλ‘ ν΄μΌν©λκΉ?
B | C
λ‘ μΆλ‘ ν΄μΌν©λλ€.TSλ νμ¬ (1), Flowλ (3)μν©λλ€. λλ (3)λ³΄λ€ (1)κ³Ό (2)λ₯Ό ν¨μ¬ λ μ νΈν©λλ€.
@Arnavion μμ λ₯Ό μλ λ¬Έμ μ μΆκ°νκ³
μ΄ μμμ :
var x = "5"; // x is inferred as string
x = 5; // x is infered as number now
x.toString(); // Compiles, since number has a toString method
x += 5; // Compiles since x is a number
console.log(x.length) // error x is a number
μ§κΈ :
var x = '';
if (true) {
x = 5;
}
μ΄ μμμ xλ string | number
κ·Έλ¦¬κ³ λ§μ½ λ΄κ° :
1. var x = '';
2. if (true) {
3. x = 5;
4. }
5. x*=5;
1 νμ myFile.js line 1 string this type is incompatible with myFile.js line 5 number
λΌλ μ€λ₯κ° λ°μνμ΅λλ€.
λλ μ¬μ ν μ¬κΈ°μμ λ Όλ¦¬λ₯Ό νμ ν΄μΌνλ€. ....
λ΄κ° μμ νλ¦μ λν ν₯λ―Έλ‘μ΄ μ μ΄ μμ΅λλ€.
function test(t: Object) { }
test('string'); //error
κΈ°λ³Έμ μΌλ‘ 'Object'λ λ€λ₯Έ κΈ°λ³Έ μ νκ³Ό νΈνλμ§ μμ΅λλ€.
'μΌλ° ν΄μλ μΊ‘μ²'λ νμ€ν TSμ νμ κΈ°λ₯μ λλ€!
@fdecampredon λ€ λ§μμ. var x = "5"; x = 5;
xμ μΆλ‘ λ μ νμ΄ number
μ
λ°μ΄νΈλ©λλ€. λ λ²μ§Έ ν λΉ μ£Όμμ if (true) { }
λ₯Ό μΆκ°νλ©΄ typecheckerλ λ ν λΉ μ€ νλκ° μ ν¨νλ€κ³ κ°μ νλλ‘ μμ¬μ μΆλ‘ λ μ νμ΄ λμ number | string
λ©λλ€.
number | string
λ *
μ°μ°μλ₯Ό μ§μνμ§ μκΈ° λλ¬Έμ myFile.js line 1 string this type is incompatible with myFile.js line 5 number
μ€λ₯κ° μ¬ λ°λ¦
λλ€ (μ λμ¨ μ νμ νμ©λλ μ μΌν μ°μ°μ λͺ¨λ μ νμ λͺ¨λ μ°μ°μ κ΅μ°¨μ μ
λλ€. λ
Έμ‘°). μ΄λ₯Ό νμΈνκΈ° μν΄ x += 5
λ³κ²½νλ©΄ μ»΄νμΌλλ κ²μ λ³Ό μ μμ΅λλ€.
if (true)
λ₯Ό κ°λλ‘ λ΄ λκΈμ μμ λ₯Ό μ
λ°μ΄νΈνμ΅λλ€.
'μΌλ° ν΄μλ μΊ‘μ²'λ νμ€ν TSμ νμ κΈ°λ₯μ λλ€!
+1
@Arnavion , μ {}
λ³΄λ€ B | C
{}
λ₯Ό μ νΈνλμ§ λͺ¨λ₯΄κ² μ΅λλ€. B | C
μΆλ‘ νλ©΄ μΌλ°μ μΌλ‘ μ ν μμ€ν
μ λ°λμ§ν μμ± μΈ μ νμ±μ μμμν€μ§ μκ³ μ ν κ²μ¬νλ νλ‘κ·Έλ¨ μ§ν©μ΄ νμ₯λ©λλ€.
μ
declare function foo<T>(x:T, y: T): T;
var r = foo(1, "a"); // no problem, T is just string|number
Tλ κ²μΌλ‘ μΆμ λλ€λ μ μ μ μΈ μ΄λ―Έ νμ¬μ μ»΄νμΌλ¬μμ typechecks {}
보λ€λ string | number
. μ΄κ²μ μ νμ±μ νννμ§λ μμ§λ§ μΌλ°μ μΌλ‘ λ μ μ©ν©λλ€.
Infering number | string
λμ {}
λμκ² λ¬Έμ κ° λ³΄μ΄μ§ μλλ€. μ΄ νΉλ³ν κ²½μ°μλ μ ν¨ν νλ‘κ·Έλ¨ μ§ν©μ΄ νμ₯λμ§ μμ§λ§ μ νμ΄ κ΅¬μ‘°λ₯Ό 곡μ νλ©΄ μ ν μμ€ν
μ΄μ΄λ₯Ό μΈμνκ³ λͺ κ°μ§ μΆκ° λ©μλ λ° / λλ μμ±μ μ ν¨νκ² λ§λλ κ²μ κ°μ λ κ²μ²λΌ 보μ
λλ€.
B | C
μΆλ‘
λ¬Έμμ΄μ΄λ μ«μκ° λ μμλ κ²μ + μ°μ°μ νμ©νλ κ²μ μ°μ°μ΄ μλ‘ μ ν μ μ¬νμ§ μκΈ° λλ¬Έμ μ νμ±μ νΌμνλ€κ³ μκ°ν©λλ€. μμ μ΄ κ³΅ν΅ κΈ°λ³Έ ν΄λμ€ (λ΄ μ΅μ 2)μ μνλ μν©κ³Όλ λ€λ¦ λλ€.μ΄ κ²½μ° μ μ¬μ±μ κΈ°λν μ μμ΅λλ€.
+ μ°μ°μλ λ κ°μ νΈνλμ§ μλ μ€λ²λ‘λκ° μκΈ° λλ¬Έμ νΈμΆ ν μ μμ΅λλ€. νλλ λ μΈμκ° μ«μμ΄κ³ λ€λ₯Έ νλλ λ λ€ λ¬Έμμ΄μ λλ€. B μ΄ν | Cλ λ¬Έμμ΄κ³Ό μ«μλ³΄λ€ μ’μ΅λλ€. λ μ€λ²λ‘λμμ μΈμλ‘ νμ©λμ§ μμ΅λλ€.
ν¨μκ° μΈμμ μ΄λ³ μ±μ μ μΈνκ³ λ λ¬Έμ κ° λ μ μμ΅λκΉ?
var foo: string; console.log(foo + 5); console.log(foo + document);
μ»΄νμΌνκΈ° λλ¬Έμ λ¬Έμμ΄ + μ°μ°μκ° μ€λ₯Έμͺ½μ μ무κ²λ νμ©νμ§ μμμΌλ―λ‘ string | number
μ + <number>
λ₯Ό μ ν¨ν μ°μ°μΌλ‘ κ°μ§ κ²μ΄λΌκ³ μκ°νμ΅λλ€. νμ§λ§ λΉμ λ§μ΄ λ§μ΅λλ€ :
error TS2365: Operator '+' cannot be applied to types 'string | number' and 'number'.
λ§μ λκΈμ΄ Flowμμ μ νμ μλ νμ₯μ μ΄μ μ λ§μΆ μμ΅λλ€. λ κ²½μ° λͺ¨λ μ£Όμμ μΆκ°νμ¬ μνλ λμμ κ°μ§ μ μμ΅λλ€. TSμμλ μ μΈ : var x: number|string = 5;
μμ λͺ
μ μ μΌλ‘ νμ₯νκ³ Flowμμλ μ μΈ : var x: number = 5;
μμ μ νν©λλ€. νμ
μ μΈμ΄ νμνμ§ μμ κ²½μ°λ μ¬λλ€μ΄ κ°μ₯ λ§μ΄ μ¬μ©νλ κ²½μ° μ¬μΌνλ€κ³ μκ°ν©λλ€. λ΄ νλ‘μ νΈμμλ var x = 5; x = 'five';
κ° κ³΅μ©μ²΄ μ νλ³΄λ€ λ μμ£Ό μ€λ₯κ° λ κ²μΌλ‘ μμν©λλ€. κ·Έλμ λλ TSκ° μ΄κ²μ λν μΆλ‘ μ κ°μ§κ³ μλ€κ³ λ§νκ³ μΆμ΅λλ€.
κ°μ₯ κ°μΉ μλ€κ³ μκ°νλ Flow κΈ°λ₯μ?
?string
보λ€λ nullμ΄ μλ μμ μ string!
λ‘ λ λ§μ΄ μμν©λλ€. λλ μ΄κ²μ λν΄ μΈ κ°μ§ λ¬Έμ λ₯Ό λ³Έλ€.undefined
μ²λ¦¬ λ°©λ²? _ (Flowλμ΄ λ¬Έμ λ₯Ό ννΌν©λλ€.) _mixed
λ° Object
.Object.keys(3)
λ₯Ό μλνλ©΄ μ€λ₯κ° λ°μν©λλ€. κ·Έλ¬λ μ£μ§ μΌμ΄μ€κ° κ±°μ μλ€κ³ μκ°νλ―λ‘ μ΄κ²μ μ€μνμ§ μμ΅λλ€.μλ ν΅ν© μ ν μΆλ‘ : "μ ν μΆλ‘ "μ΄ μ ν μ μΈμΌλ‘ μ νλλ€κ³ κ°μ ν©λλ€. μλ΅ λ νμ μ μΈμ μμ μ μΌλ‘ μ μΆνλ λ©μ»€λμ¦μ
λλ€. Goμμ :=
μ²λΌ. λλ μ ν μ΄λ‘ κ°λ μλμ§λ§ λ΄κ° μ΄ν΄νλ ν μ ν μΆλ‘ μ ν λΉλλ ννμμ μ νμμ μ μΆ λ λͺ¨λ μμ μ λ³μ μ μΈ (λλ ν¨μ μΈμ)μ λͺ
μ μ μ ν μ£Όμμ μΆκ°νλ μ»΄νμΌλ¬ ν¨μ€μ
λλ€. λ΄κ° μλ ν, μ΄κ²μ΄ λ€λ₯Έ λͺ¨λ μ νμ μΆλ‘ λ©μ»€λμ¦μμ μλνλ λ°©μμ
λλ€. C #, Haskell, Go, λͺ¨λμ΄ λ°©μμΌλ‘ μλν©λλ€. μλλ©΄?
λλ μ€μνμ JSκ° TS μλ―Έλ‘ μ μ¬μ©νλλ‘ νμ©νλ κ²μ λν μ£Όμ₯μ μ΄ν΄νμ§λ§, λμ λ€λ₯Έ μΈμ΄λ₯Ό λ°λ₯΄λ κ²μ΄ μ’μ μ μΌ κ²μ λλ€. μ νμ κ²°κ΅ JSμ TSμ λ¨μΌ μ μ μ°¨μ΄μ μ λλ€.
μ λ Flux μμ΄λμ΄λ₯Ό λ§μ΄ μ’μν©λλ€.νμ§λ§μ΄ μμ΄λμ΄κ° μ€μ λ‘ μ΄λ° μμΌλ‘ μ΄λ£¨μ΄ μ‘λ€λ©΄ ... 그건 κ·Έλ₯ μ΄μν©λλ€.
λμ΄ μλ μ νμ νλ μ ν μμ€ν μ νμ κΈ°λ₯μ²λΌ 보μ λλ€. TSμ μ½κ² μΆκ° ν μ μμ΅λκΉ?
nullableμ΄ μλ μ νμ TSμ μΆκ°νλ 볡μ‘μ±μ λν κ°λ¨ν μ½κΈ°λ₯Ό μνλ€λ©΄ https://github.com/Microsoft/TypeScript/issues/185λ₯Ό μ°Έμ‘°
Nullableμ΄ μλ μ νλ§νΌ μ’μ κ²μ μ€λλ λ리 μ¬μ©λλ λλΆλΆμ μΈμ΄μλ κΈ°λ³Έμ μΌλ‘ nullableμ΄ μλ μ ν (κΈ°λ₯μ΄ μ§μ μΌλ‘ λΉλλ κ³³)μ΄λ μΌλ°ν λ Nullable κΈ°λ₯μ΄ μ ν μμ΅λλ€. κ·Έλ¦¬κ³ λ³΅μ‘μ±κ³Ό non-nullabilityμ κ°μ΄ κΈ°λ³Έκ° (λΆλ³μ±κ³Ό μ μ¬)μ μλ€λ μ¬μ€ λλ¬Έμ μ¬μ€ νμ μΆκ° (λλ μ±κ³΅μ μΌλ‘ μΆκ°)νλ €κ³ μλν μ¬λμ κ±°μ μμ΅λλ€. μ΄κ²μ μ°λ¦¬κ° μ¬κΈ°μ κ°λ₯μ±μ κ³ λ €νκ³ μμ§ μλ€λ κ²μ μλ―Ένμ§λ μμ§λ§ νμ κΈ°λ₯μ΄λΌκ³ λΆλ₯΄μ§ μμ κ²μ λλ€.
μ€μ λ‘ λ΄κ° nullμ΄ μλ μ νμ λμΉλ§νΌ, νλ‘μ°μμ λμΉ μ€μ κΈ°λ₯μ μΌλ° μΊ‘μ²μ
λλ€. tsκ° λͺ¨λ μΌλ°μ {}
ν΄μνλ€λ μ¬μ€μ μΌλΆ κΈ°λ₯ ꡬ쑰, νΉν 컀λ§κ³Ό ν¨κ» μ¬μ©νκΈ°κ° μ λ§ μ΄λ ΅κ² λ§λλλ€.
κ°μΈμ μΌλ‘ μΌλ°μ μΈ μΊ‘μ² λ° λΉ null κ°λ₯μ±μ Flowμ _high_ κ° λμμ λλ€. λ€λ₯Έ μ€λ λλ₯Ό μ½μ΄ 보 κ² μ§λ§ μ¬κΈ°μ 2cλ λ£κ³ μΆμμ΅λλ€.
λΉ nullability μΆκ°μ μ΄μ μ κ±°μ λͺ¨λ λΉμ©μ κ°μΉκ° μλ€κ³ μκ°ν©λλ€. μ΄λ μ€λ₯ κ°λ₯μ±μ΄ λ§€μ° λμ 쑰건μ΄λ©° κΈ°λ³Έ null νμ© μ¬λΆκ° νμ¬ κΈ°λ³Έ μ 곡 κ°μ μ½νμν€λ λ°λ©΄ TypeScriptλ λ¨μν λͺ¨λ κ²½μ°μ ν΄λΉνλ€κ³ κ°μ νμ¬ null νμ© μ¬λΆλ₯Ό λ Όμ ν μμλ λ₯λ ₯μ΄ λΆμ‘±ν©λλ€.
ννΈ λΉνΈμμ nullableμ΄ μλ κ²μΌλ‘ μ°Ύμ μμλ λͺ¨λ λ³μμ μ£Όμμ λ¬μμ΅λλ€.
νλ‘μ° μ¬μ΄νΈμλ λ¬Έμνλμ§ μμ λ§μ μ¨κ²¨μ§ κΈ°λ₯μ΄ νλ‘μ°μ μμ΅λλ€. SuperType λ°μΈλ© λ° μ‘΄μ¬ μ ν ν¬ν¨
κ°μ₯ μ μ©ν λκΈ
κ°μΈμ μΌλ‘ μΌλ°μ μΈ μΊ‘μ² λ° λΉ null κ°λ₯μ±μ Flowμ _high_ κ° λμμ λλ€. λ€λ₯Έ μ€λ λλ₯Ό μ½μ΄ 보 κ² μ§λ§ μ¬κΈ°μ 2cλ λ£κ³ μΆμμ΅λλ€.
λΉ nullability μΆκ°μ μ΄μ μ κ±°μ λͺ¨λ λΉμ©μ κ°μΉκ° μλ€κ³ μκ°ν©λλ€. μ΄λ μ€λ₯ κ°λ₯μ±μ΄ λ§€μ° λμ 쑰건μ΄λ©° κΈ°λ³Έ null νμ© μ¬λΆκ° νμ¬ κΈ°λ³Έ μ 곡 κ°μ μ½νμν€λ λ°λ©΄ TypeScriptλ λ¨μν λͺ¨λ κ²½μ°μ ν΄λΉνλ€κ³ κ°μ νμ¬ null νμ© μ¬λΆλ₯Ό λ Όμ ν μμλ λ₯λ ₯μ΄ λΆμ‘±ν©λλ€.
ννΈ λΉνΈμμ nullableμ΄ μλ κ²μΌλ‘ μ°Ύμ μμλ λͺ¨λ λ³μμ μ£Όμμ λ¬μμ΅λλ€.