conditional type 0: นี่คือโพสต์ที่เกี่ยวข้องกับหัวข้อนี้
This year TypeScript gained a new feature that punches far above its weight.
Working through our (enormous) backlog of unsorted TypeScript “Suggestions” and it’s remarkable how many of them
are solved by conditional types.
— Ryan Cavanaugh, TypeScript maintainer
Conditional types probably aren’t something you’ll write every day, but you might end up using them indirectly all
the time. That’s because they’re great for ‘plumbing’ or ‘framework’ code, for dealing with API boundaries and
other behind-the-scenes kinda stuff. So, dear reader, read on! It’s always good to learn how the sausage is made.
Then you can make sausage of your own.
Typewurst! 🌭
Note: This is a straightforward adaptation of a 35-minute presentation given at
Futurice London’s TypeScript Night meetup,
and therefore provides more context than an ordinary blog post might. I hope a lot of that context is interesting
and useful even for seasoned TypeScript developers. If you’d prefer a no-frills experience, check out the
TypeScript 2.8 Release notes .
Table of Contents
Your first conditional type
Here’s some plain JavaScript
1
2
3
4
5
function
process
(
text
)
{
return
text
&&
text
.
replace
(
/f/g
,
"p"
)
}
process
(
"foo"
).
toUpperCase
()
Reading the code, it’s clear to a human that the .toUpperCase()
method call is safe. We can tell that whenever a
string is passed in to process
, a string will be returned.
But notice that we could also pass something like null
into the function, in which case null
would be returned.
Then calling .toUpperCase()
on the result would be an error.
Let’s add basic types to this function so we can let TypeScript worry about whether we are using it safely or not.
1
2
3
function
process
(
text
: string
|
null
)
:
string
|
null
{
return
text
&&
text
.
replace
(
/f/g
,
"p"
)
}
Seems sensible. What happens if we try to use it like before?
1
2
// ⌄ Type Error! :(
process
(
"foo"
).
toUpperCase
()
TypeScript complains because it thinks that the result of process("foo")
might be null
, even though we clever
humans know that it won’t be. It can’t figure out the runtime semantics of the function on its own.
One way of helping TS understand the function better is to use ‘overloading’. Overloading involves providing
multiple type signatures for a single function, and letting TypeScript figure out which one to use in any given
context.
1
2
3
4
5
function
process
(
text
: null
)
:
null
;
function
process
(
text
: string
)
:
string
;
function
process
(
text
: any
)
{
...
}
Here we’ve said that if we pass a string
, it returns a string
, and if we pass null
, it returns null
. (The
any
type is ignored but still needs to be there for some reason 🤷️)
That works nicely:
1
2
3
4
// All clear!
process
(
"foo"
).
toUpperCase
()
// ⌄ Type Error! :)
process
(
null
).
toUpperCase
()
But there’s another use case that doesn’t work:
1
2
3
4
declare
const
maybeFoo
: string
|
null
// ⌄ Type Error! :(
process
(
maybeFoo
)
TypeScript won’t let us pass something that is of type string | null
because it’s not smart enough to collapse
the overloaded signatures when that’s possible. So we can either add yet another overload signature for the
string | null
case, or we can be like (╯°□°)╯︵
┻━┻ and switch to using conditional types.
1
2
3
4
5
function
process
<
T
extends
string
|
null
>
(
text
: T
)
:
T
extends
string
?
string
:
null
{
...
}
Here we’ve introduced a type variable T
for the text
parameter. We can then use T
as part of a conditional
return type: T extends string ? string : null
. You probably noticed that this looks just like a ternary
expression! Indeed, it’s doing the same kind of thing, but within the type system at compile time.
And that takes care of all our use cases:
1
2
3
typeof
process
(
"foo"
)
// => string
typeof
process
(
null
)
// => null
typeof
process
(
maybeFoo
)
// => string | null
So that’s what a conditional type is! A kind of ternary type expression. It always has this form:
1
A
extends
B
?
C
: D
A
, B
, C
, and D
can be any old type expressions, but all the important stuff is happening on the left there.
In the A extends B
condition.
Assignability
This extends
keyword is the heart of a conditional type. A extends B
means precisely that any value of type A
can safely be assigned to a variable of type B
. In type system jargon we can say that “A is assignable to B”.
1
2
3
declare
const
a
: A
const
b
: B
=
a
// type check succeeds only if A is assignable to B
TypeScript decides which types are assignable to each other using an approach called ‘structural typing’. This kind
of type system started appearing in mainstream languages relatively recently (in the last 10 years or so), and
might be a little counterintuitive if you come from a Java or C# background.
You may have heard of ‘duck typing’ in relation to dynamically-typed languages. The phrase ‘duck typing’ comes from
the proverb
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
In duck typing, you judge a thing by how it behaves, rather than what it is called or who its parents are. It’s a
kind of meritocracy. Structural typing is a way of applying that same idea to a static compile-time type system.
So TypeScript only cares about what types can do, not what they are called or where they exist in a type hierarchy.
Take this simple example:
1
2
3
4
5
6
7
class
A
{}
class
B
{}
const
b
: B
=
new
A
()
// ✔ all good
const
a
: A
=
new
B
()
// ✔ all good
new
A
()
instanceof
B
// => false
TypeScript is happy treating two completely unrelated classes as equivalent because they have the same structure
and the same capabilities. Meanwhile, when checking the types at runtime, we discover that they are actually not
equivalent.
This is a notable example of where the semantics of TypeScript are at odds with JavaScript. It might seem like a
problem, but in practice structural typing is a lot more flexible than Java-esque ‘nominal’ typing, where names and
hierarchy matter. The two aren’t mutually exclusive, however. Some languages, like Scala and Flow, allow you to mix
and match to suit particular problems.
Aside from that, the way that assignability works with structural typing is very intuitive.
1
2
3
4
5
6
7
8
9
10
11
12
13
interface
Shape
{
color
: string
}
class
Circle
{
color
: string
radius
: number
}
// ✔ All good! Circles have a color
const
shape
: Shape
=
new
Circle
()
// ✘ Type error! Not all shapes have a radius!
const
circle
: Circle
=
shape
Speaking structurally we can say that A extends B
is a lot like ‘A
is a superset of B
‘, or, to be more
verbose, ‘A
has all of B
‘s properties, and maybe some more’.
There’s one minor caveat though, and that’s with ‘literal’ types. In TypeScript you can use literal values of
primitive types as types themselves.
1
2
3
4
let
fruit
:
"banana"
=
"banana"
// Type Error! "apple" is not assignable to "banana"
fruit
=
"apple"
The string "banana"
doesn’t have more properties than any other string
. But the type "banana"
is still more
specific than the type string
.
So another way to think of A extends B
is like ‘A
is a possibly-more-specific version of B
‘.
Which brings us to ‘top’ and ‘bottom’ types: the least and most specific types, respectively.
In type theory a ‘top’ type is one which all other types are assignable to. It is the type you use to say “I have
absolutely no information about what this value is”. Think of it as the union of all possible types:
1
type
Top
=
string
|
number
|
{
foo
: Bar
}
|
Baz
[]
|
...
|
∞
TypeScript has two top types: any
and unknown
.
- Using
any
is like saying “I have no idea what this value looks like. So, TypeScript, please assume I’m using it
correctly, and don’t complain if anything I do seems dangerous”. - Using
unknown
is like saying “I have no idea what this value looks like. So, TypeScript, please make sure I
check what it is capable of at run time.”
A ‘bottom’ type is one which no other types are assignable to, and that no values can be an instance of. Think of
it as the empty union type:
1
type
Bottom
=
∅
TypeScript has one bottom type: never
. That’s a nice descriptive name because it literally means this can never
happen.
Top and bottom types are useful to know about when working with conditional types. never
is especially useful
when using conditional types to refine unions…
Refining unions with distributive conditional types
Conditional types let you filter out particular members of a union type. To illustrate, let’s say we have a union
type called Animal
:
1
type
Animal
=
Lion
|
Zebra
|
Tiger
|
Shark
And imagine that we needed to write a function that used only those animals which are also cats. We might write
some helper type called ExtractCat
to do that:
1
2
3
4
type
ExtractCat
<
A
>
=
A
extends
{
meow
()
:
void
}
?
A
: never
type
Cat
=
ExtractCat
<
Animal
>
// => Lion | Tiger
I know lions and tigers don’t meow, but how cute would it be if they did ^_^
This seemed vague and magical to me at first. Let’s see what TypeScript is doing under the hood when it evaluates
ExtractCat<Animal>
.
First, it applies ExtractCat
recursively to all the members of Animal
:
1
2
3
4
5
type
Cat
=
|
ExtractCat
<
Lion
>
|
ExtractCat
<
Zebra
>
|
ExtractCat
<
Tiger
>
|
ExtractCat
<
Shark
>
Then it evaluates the conditional types:
1
type
Cat
=
Lion
|
never
|
Tiger
|
never
And then something fun happens… Remember that no values can ever be of type never
? That makes it totally
meaningless to include never
in a union type, so TypeScript just gets rid of it.
1
type
Cat
=
Lion
|
Tiger
The TypeScript jargon for this kind of conditional type is distributive conditional type.
That ‘distribution’, where the union is unrolled recursively, only happens when the thing on the left of the
extends
keyword is a plain type variable. We’ll see what that means and how to work around it in the next
section.
A real use-case for distributive conditional types.
A while ago I was building a Chrome extension. It had a ‘background’ script and a ‘view’ script that ran in
different execution contexts. They needed to communicate and share state, and the only way to do that is via
serializable message passing. I took inspiration from Redux and defined a global union of interfaces called
Action
to model the messages that I wanted to be able to pass between the contexts.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type
Action
=
|
{
type
:
"INIT"
}
|
{
type
:
"SYNC"
}
|
{
type
:
"LOG_IN"
emailAddress
: string
}
|
{
type
:
"LOG_IN_SUCCESS"
accessToken
: string
}
// ...
And then there was a global dispatch
function that I could use directly to broadcast messages across contexts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
declare
function
dispatch
(
action
: Action
)
:
void
// ...
dispatch
({
type
:
"INIT"
})
// ...
dispatch
({
type
:
"LOG_IN"
,
emailAddress
:
})
// ...
dispatch
({
type
:
"LOG_IN_SUCCESS"
,
accessToken
:
"038fh239h923908h"
})
Try it in the TypeScript playground
This API is typesafe and it plays well with my IDE’s autocomplete and I could have left it there. I could have
moved on to other things.
But there’s this little voice inside my head. I think most developers have this voice.
INT. HIPSTER CO-WORKING SPACE - DAY DAVID sits on an oddly-shaped orange chair. His MacBook rests askew on a lumpy reclaimed wood desk. He stares at colorful text on a dark screen. A tiny whisper. VOICE (V.O.) Psst! David looks around for a moment and then stares back at the laptop. VOICE (V.O.) Psst! Hey! Startled this time, David looks around again. He speaks to nobody in particular. DAVID Is someone there? VOICE (V.O.) It's me, the DRY devil. David heaves a painful sigh of recognition. DAVID Not you again! Leave me alone! DRY DEVIL (V.O.) DRY stands for "Don't Repeat Yourself" DAVID I know, you say that every time! Now get lost! DRY DEVIL (V.O.) I've noticed an issue with your code. DAVID Seriously, go away! I'm busy solving user problems to create business value. DRY DEVIL (V.O.) Every time you call `dispatch` you are typing 6 redundant characters. DAVID Oh snap! You're right! I must fix this. MONTAGE David spends the next 2 hours wrestling with TypeScript, accumulating a pile of empty coffee cups and protein ball wrappers.
We’ve all been there.
I wanted the dispatch function to work like this:
1
2
3
4
5
// first argument is the 'type'
// second is any extra parameters
dispatch
(
"LOG_IN_SUCCESS"
,
{
accessToken
:
"038fh239h923908h"
})
Deriving the type for that first argument is easy enough.
1
2
type
ActionType
=
Action
[
"type"
]
// => "INIT" | "SYNC" | "LOG_IN" | "LOG_IN_SUCCESS"
But the type of the second argument depends on the first argument. We can use a type variable to model that
dependency.
1
2
3
4
declare
function
dispatch
<
T
extends
ActionType
>
(
type
: T
,
args
: ExtractActionParameters
<
Action
,
T
>
)
:
void
Woah woah woah, what’s this ExtractActionParameters
voodoo?
It’s a conditional type of course! Here’s a first attempt at implementing it:
1
type
ExtractActionParameters
<
A
,
T
>
=
A
extends
{
type
: T
}
?
A
: never
This is a lot like the ExtractCat
example from before, where we were were refining the Animals
union by
searching for something that can meow()
. Here, we’re refining the Action
union type by searching for an
interface with a particular type
property. Let’s see if it works:
1
2
type
Test
=
ExtractActionParameters
<
Action
,
"LOG_IN"
>
// => { type: "LOG_IN", emailAddress: string }
Almost there! We don’t want to keep the type
field after extraction because then we would still have to specify
it when calling dispatch
. And that would somewhat defeat the purpose of this entire exercise.
We can omit the type
field by combining a mapped type with a conditional type and the keyof
operator.
A mapped type lets you create a new interface by ‘mapping’ over a union of keys. You can get a union of keys
from an existing interface by using the keyof
operator. And finally, you can remove things from a union using a
conditional type. Here’s how they play together (with some inline test cases for illustration):
1
2
3
4
5
6
7
8
9
10
type
ExcludeTypeKey
<
K
>
=
K
extends
"type"
?
never
: K
type
Test
=
ExcludeTypeKey
<
"emailAddress"
|
"type"
|
"foo"
>
// => "emailAddress" | "foo"
// here's the mapped type
type
ExcludeTypeField
<
A
>
=
{
[
K
in
ExcludeTypeKey
<
keyof
A
>
]
:
A
[
K
]
}
type
Test
=
ExcludeTypeField
<
{
type
:
"LOG_IN"
;
emailAddress
: string
}
>
// => { emailAddress: string }
Then we can use ExcludeTypeField
to redefine ExtractActionParameters
.
1
2
3
type
ExtractActionParameters
<
A
,
T
>
=
A
extends
{
type
: T
}
?
ExcludeTypeField
<
A
>
:
never
And now the new version of dipsatch
is typesafe!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// All clear! :)
dispatch
(
"LOG_IN_SUCCESS"
,
{
accessToken
:
"038fh239h923908h"
})
dispatch
(
"LOG_IN_SUCCESS"
,
{
// Type Error! :)
badKey
:
"038fh239h923908h"
})
// Type Error! :)
dispatch
(
"BAD_TYPE"
,
{
accessToken
:
"038fh239h923908h"
})
Try it in the TypeScript playground
But there’s one more very serious problem to address: If the action has no extra parameters, I still have to pass a
second empty argument.
1
dispatch
(
"INIT"
,
{})
That’s four whole wasted characters! Cancel my meetings and tell my partner not to wait up tonight! We need to
fix. this.
The naïve thing to do would be to make the second argument optional. That would be unsafe because, e.g. it would
allow us to dispatch a "LOG_IN"
action without specifying an emailAddress
.
Instead, let’s overload the dispatch
function.
1
2
3
4
5
6
7
8
9
10
// And let's say that any actions that don't require
// extra parameters are 'simple' actions.
declare
function
dispatch
(
type
: SimpleActionType
)
:
void
// this signature is just like before
declare
function
dispatch
<
T
extends
ActionType
>
(
type
: T
,
args
: ExtractActionParameters
<
Action
,
T
>
)
:
void
type
SimpleActionType
=
ExtractSimpleAction
<
Action
>
[
'type'
]
How can we define this ExtractSimpleAction
conditional type? We know that if we remove the type
field from an
action and the result is an empty interface, then that is a simple action. So something like this might work
1
type
ExtractSimpleAction
<
A
>
=
ExcludeTypeField
<
A
>
extends
{}
?
A
: never
Except that doesn’t work. ExcludeTypeField<A> extends {}
is always going to be true, because {}
is like a top
type for interfaces. Pretty much everything is more specific than {}
.
We need to swap the arguments around:
1
type
ExtractSimpleAction
<
A
>
=
{}
extends
ExcludeTypeField
<
A
>
?
A
: never
Now if ExcludeTypeField<A>
is empty, the condition will be true, otherwise it will be false.
But this still doesn’t work! On-the-ball readers might remember this:
That ‘distribution’, where the union is unrolled recursively, only happens when the thing on the left of the
extends
keyword is a plain type variable. We’ll see what that means and how to work around it in the next
section.
— Me, in the previous section
Type variables are always defined in a generic parameter list, delimited by <
and >
. e.g.
1
2
3
4
5
type
Blah
<
These
,
Are
,
Type
,
Variables
>
=
...
function
blah
<
And
,
So
,
Are
,
These
>
()
{
...
}
And if you want a conditional type to distribute over a union, the union a) needs to have been bound to a type
variable, and b) that variable needs to appear alone to the left of the extends
keyword.
e.g. this is a distributive conditional type:
1
type
Blah
<
Var
>
=
Var
extends
Whatever
?
A
: B
and these are not:
1
2
type
Blah
<
Var
>
=
Foo
<
Var
>
extends
Whatever
?
A
: B
type
Blah
<
Var
>
=
Whatever
extends
Var
?
A
: B
When I discovered this limitation I thought that it exposed a fundamental shortcoming in the way distributive
conditional types work under the hood. I thought it might be some kind of concession to algorithmic complexity. I
thought that my use case was too advanced, and that TypeScript had just thrown its hands up in the air and said,
“Sorry mate, you’re on your own”.
But it turns out I was wrong. It is just a pragmatic language design decision to avoid extra syntax, and you can
work around it easily:
1
2
3
4
5
type
ExtractSimpleAction
<
A
>
=
A
extends
any
?
{}
extends
ExcludeTypeField
<
A
>
?
A
:
never
:
never
All we did is wrap the meat of our logic in a flimsy tortilla of inevitability, since the outer condition
A extends any
will, of course, always be true.
And finally we can delete those four characters 🎉🕺🏼💃🏽🎈
1
dispatch
(
"INIT"
)
That’s one yak successfully shaved ✔
TypeScript provides a couple of built-in types that we could have used in this section:
1
2
3
4
5
// Exclude from U those types that are assignable to T
type
Exclude
<
U
,
T
>
=
U
extends
T
?
never
: U
// Extract from U those types that are assignable to T
type
Extract
<
U
,
T
>
=
U
extends
T
?
U
: never
e.g. instead of defining ExcludeTypeField
like this:
1
type
ExcludeTypeField
<
A
>
=
{
[
K
in
ExcludeTypeKey
<
keyof
A
>
]
:
A
[
K
]
}
we could have done this:
1
type
ExcludeTypeField
<
A
>
=
{
[
K
in
Exclude
<
keyof
A
,
"type"
>
]
:
A
[
K
]
}
And instead of defining ExtractActionParameters
like this:
1
2
3
type
ExtractActionParameters
<
A
,
T
>
=
A
extends
{
type
: T
}
?
ExcludeTypeField
<
A
>
:
never
we could have done this:
1
type
ExtractActionParameters
<
A
,
T
>
=
ExcludeTypeField
<
Extract
<
A
,
{
type
: T
}
>>
💡 Exercise for the intrepid reader
Notice that this still works.
1
dispatch
(
"INIT"
,
{})
Use what you’ve learned so far to make it an error to supply a second argument for ‘simple’ actions.
Destructuring types with infer
Conditional types have another trick up their sleeve: the infer
keyword. It can be used anywhere in the type
expression to the right of the extends
keyword. It gives a name to whichever type would appear in that place.
e.g.
1
2
3
4
5
6
type
Unpack
<
A
>
=
A
extends
Array
<
infer
E
>
?
E
: A
type
Test
=
Unpack
<
Apple
[]
>
// => Apple
type
Test
=
Unpack
<
Apple
>
// => Apple
It handles ambiguity gracefully:
1
2
type
Stairs
=
Unpack
<
Apple
[]
|
Pear
[]
>
// => Apple | Pear
You can even use infer
multiple times.
1
2
3
4
5
6
7
type
Flip
<
T
>
=
T
extends
[
infer
A
,
infer
B
]
?
[
B
,
A
]
:
never
type
Stairs
=
Flip
<
[
Pear
,
Apple
]
>
// => [Apple, Pear]
type
Union
<
T
>
=
T
extends
[
infer
A
,
infer
A
]
?
A
: never
type
Stairs
=
Union
<
[
Apple
,
Pear
]
>
// => Apple | Pear
Other built-in conditional types
We’ve already seen Exclude
and Extract
, and TypeScript provides a few other conditional types out of the box.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Exclude null and undefined from T
type
NonNullable
<
T
>
=
T
extends
null
|
undefined
?
never
: T
// Obtain the parameters of a function type in a tuple
type
Parameters
<
T
>
=
T
extends
(...
args
: infer
P
)
=>
any
?
P
: never
// Obtain the parameters of a constructor function type in a tuple
type
ConstructorParameters
<
T
>
=
T
extends
new
(...
args
: infer
P
)
=>
any
?
P
: never
// Obtain the return type of a function type
type
ReturnType
<
T
>
=
T
extends
(...
args
: any
[])
=>
infer
R
?
R
: any
// Obtain the return type of a constructor function type
type
InstanceType
<
T
>
=
T
extends
new
(...
args
: any
[])
=>
infer
R
?
R
: any
Further reading
[Update] Conditional Sentence Câu If | conditional type 0 – NATAVIGUIDES
Conditional Sentence (câu điều kiên if) cũng được tính là một câu phức với independent clause và dependent clause. Điểm đặc biệt của câu điều kiện này là chúng dành để đưa ra giả định. Giả định thì có thể đúng, có thể sai. Có thể là hoàn toàn không có thật, có thể là có thể xảy ra. Trong bài này, chúng ta sẽ tập trung xem qua tất cả những điểm ngữ pháp liên quan đến việc đưa ra câu giả định (hypothesis).
Cần lưu ý là Conditional Sentence If – Câu If chỉ là một trong nhiều cách để đưa GIả Định mà thôi. Có thể các bạn sẽ muốn khám phá toàn bộ chuyên đề Conditional Sentence – Câu Điều Kiện đấy.
Conditional Sentence Câu If
Modal Verb – Trợ Động Từ – có khá nhiều loại, và chúng thêm một hàm ý nhất định vào trong động từ. Tuy nhiên, khi chúng ta dùng chúng trong câu điều kiện, chúng lại được phân loại và biến đổi một chút nữa. Đó là lý do chúng ta nên tìm hiểu về chúng trước khi xem qua bài Conditional Sentence Câu IF.
Các bạn có thể tìm hiểu về trợ động từ trong câu điều kiện tại bài Modal Verb in Conditional Sentence.
Loại câu điều kiện đầu tiên phải kể đến là Zero Conditional Sentence. Chúng dành cho những câu luôn luôn đúng(?). Và cách sử dụng của chúng cũng khá đặc biệt. Zero Conditional Sentence là loại câu điều kiện duy nhất (trong câu IF) không cần dùng Modal Verb ở mệnh đề chính.
Các bạn có thể tìm hiểu trọn vẹn về loại câu IF này tại bài Zero Conditional Sentence – Câu Điều Kiện 0.
Câu điều kiện loại 1, hay còn gọi là có thật ở hiện tại. Tuy nhiên, người ta còn dùng khái niệm này để chỉ câu điều kiện có thể xảy ra ở quá khứ.
Ở hiện tại thì đơn giản rồi nhưng khi nói ở quá khứ mọi việc lại trở nên phức tạp hơn. Vì vậy, thầy đã có một bài riêng cho nó. Các bạn xem qua bài Conditional Type 1 – Câu điều kiện loại một để tìm hiểu thêm nhé.
Đây là câu điều kiện loại 2, dành riêng cho những sự vật sự việc không thể diễn ra ở hiện tại. Khi chúng ta muốn đề cập đến sự bất khả thi (về khả năng diễn ra) của một hành động ở hiện tại, chúng ta sẽ dùng loại câu này.
Dùng câu điều kiện loại 2 như thế nào? Cần chú ý điều gì? Mời các bạn xem bài Conditional Sentence Type 2 – Câu Điều Kiện Loại 2 nhé.
Đây là nhóm “đô con” nhất trong mớ câu IF. Câu điều kiện loại 3 cho phép bạn diễn đạt những hành động không thể xảy ra trong quá khứ. Cấu trúc này được dùng để giả định những sự việc đã xảy ra và không thể thay đổi được.
Các bạn có thể tham khảo toàn bộ bài viết về câu IF này tại Conditional Type 3 – Câu Điều Kiện Loại 3.
Và cuối cùng là các trường hợp kết hợp câu điều kiện ở những mốc thời gian khác nhau. Có thể là ở quá khứ với hiện tại hoặc hiện tại với quá khứ. Nhưng dù như thế nào thì chỉ có mệnh đề không thật chơi với mệnh đề không thật. Và giả định có thật đi với giả định có thật.
Trong bài này, chúng ta sẽ cùng tìm hiểu về các cách kết hợp những mệnh đều câu điều kiện lại. Các bạn hãy đọc bài Mixed Conditional Sentences nhé.
Một Số Lưu Ý
Ngoài ra có một số lưu ý sau khi chúng ta sử dụng câu IF
What If + Clause?
Khi chúng ta dùng What if + mọt mệnh đề, người nghe sẽ hiểu ngầm một trong hai trường hợp:
- What if + Clause? =
What would happen if + Clause:
không thật ở
hiện tại
- Hey, what if the sun rose in the West?
- I have too much work to do. What if there were 48 hours in a day?
- What if + Clause? =
What would have happened + if + Clause
: không thật ở
quá khứ.
- Well, what if Steve hadn’t been Captain America?
- I didn’t see him yesterday, so he broke up with me. What if I had seen him yesterday?
Các bạn chú ý là cả hai phần trên đều dùng cho KHÔNG THẬT (Unreal) nhé. Một cái không thật ở hiện tại (dùng Past Subjunctive, nghĩa là Simple Past, nhưng WERE cho tất cả các ngôi), một cái ở quá khứ (dùng Past Perfect).
If + it is + adjective = If + ADJECTIVE
Chúng ta có thể rút gọn “if it is adjective” thành “if adjective.” Rất đơn giản, chỉ việc bỏ it is đi và không thay đổi gì thêm:
- If it is possible, please call me.
=If possible
, please call me. - I think you should kiss her if it is necessary.
=I think you should kiss herif necessary
. - If it is important to you, I will do it.
=If important
, I will do it.
If so/ If not
Chúng ta có thể dùng IF kết hợp với SO (khẳng định) hoặc NOT (phủ định) để thay thế cho một câu phía trước đó. Ví dụ:
- There is a possibility that Jane refuses our offer.
If so
, we’ll have to find another person.
(=If Jane refuses our offer, we’ll have to find another person.) - Perhaps Tom will come.
If not,
I’ll take his place.
(=If Tom doesn’t come, I’ll take his place.) - Perhaps Tom won’t come.
If not
, I’ll take his place.
(=If Tom doesn’t come, I’ll take his place.)
Ồh, hai ví dụ cuối kỳ lạ đúng không? Tại tiếng Anh nó quy định thế các bạn ạ. Khi vế trước phủ định thì chúng ta dùng IF NOT sẽ hiểu là “nếu như vậy.” Trong trường hợp khẳng định thì chúng ta dùng IF NOT lại hiểu là “nếu không như vậy.”
Modal Verb in Conditional Clauses
Phần lớn trường hợp, trong mệnh đề chứ IF sẽ không được sử dụng Modal Verbs. Tuy nhiên, ở một số trường hợp nhất định, chúng ta có thể sử dụng Modal verb trong mệnh đề chứa IF để đưa thêm một nét nghĩa nhất định vào động từ.
+
Khi ta dùng Should trong vế câu điều kiện, người nghe sẽ hiểu là hành động / sự kiện đó được diễn ra một cách bất ngờ, vô tình, không có tính toán.
(nếu vô tình gặp được Carol)
Ngoài ra còn một trường hợp kết hợp với modal verb là:
If + will/would
Chúng ta còn có thể sử dụng will và would trong mệnh đề IF để:
- Diễn tả ý “tự nguyện / tự giác / đồng ý” làm điều gì:
- (nếu Clare đồng ý gặp chúng ta ở sân bay).
- (nếu mày chịu dừng la một chút thì tao sẽ giải thích cho).
…
- Nhấn mạnh sự nghi ngờ của chúng ta tới kết quả ở mệnh đề chính:
- (nếu mà chạy cứu được trái đất thì ok, tao ngừng chạy).
- If it really would be anything that makes her love me, I’d do right now.
Chúng ta có thể đảo ngữ câu điều kiện để nhấn mạnh sự giả định đấy. Các bạn theo dõi bài viết Inversion of Conditional Sentences nhé.
Và đó là tất cả những điểm ngữ pháp có thể đưa ra giả định và câu điều kiện If. Thầy nghĩ các bạn sẽ muốn xem thêm toàn bộ thông tin về Conditional Sentence – Câu Điều Kiện đấy. Vì câu If chỉ là một phần nhỏ trong đó mà thôi.
Nếu bạn thấy bài viết này hữu ích, hãy kết nối với LearningEnglishM qua kênh Youtube nhé! Thank you!
Related
Zero conditional with examples | English grammar lesson
In this lesson you will learn the use and meaning of zero conditional sentences in English.
I give you an explanation of the form with lots of examples as well as what verb tenses are used and why.
This video will be particularly useful for ESL students as well as for other teachers wanting to learn how to teach zero conditionals.
Private English lessons \u0026 speaking practice: http://goo.gl/Bhqc08
Here are some other related English videos:
Introduction to conditionals: http://www.youtube.com/watch?v=WPDpe_WuCS8
Playlists:
Grammar: http://www.youtube.com/playlist?list=PL6BDo90oiwpS4_AM1c0s0ozpROeE2A9ff
General advice: https://www.youtube.com/playlist?list=PL6BDo90oiwpQiPot5bKFKZ2wQAk_ESR6_
Listening practice: http://www.youtube.com/playlist?list=PL6BDo90oiwpRdmnAzmYwdc0Az0ZOG2XNA
Vocabulary: http://www.youtube.com/playlist?list=PL6BDo90oiwpTlYAYSitjwWn29BEdCBi9j
Andrew,
Crown Academy of English
http://www.crownacademyenglish.com
https://twitter.com/Crown_English
http://www.youtube.com/user/CrownAcademyEnglish
Photo credits:
“Stylish Portrait Of Handsome Businessman” Image courtesy of stockimages | FreeDigitalPhotos.net
“Portrait Of A Businesswoman” Image courtesy of stockimages | FreeDigitalPhotos.net
“Business Women Pointing” Image courtesy of photostock | FreeDigitalPhotos.net
“Professional Business Executive” Image courtesy of stockimages | FreeDigitalPhotos.net
“Young Businesswoman” Image courtesy of photostock | FreeDigitalPhotos.net
“Young Uk Supporter Holding National Flag” Image courtesy of stockimages | FreeDigitalPhotos.net
“Can’t Hear Clearly, Eavesdropping” Image courtesy of stockimages | FreeDigitalPhotos.net
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูเพิ่มเติม
All conditionals in English – 0 1 2 3 and mixed – English grammar lesson
This lesson is a review of all the conditionals in English. The zero conditional, the first conditional, the second conditional, the third conditional and mixed conditionals. It briefly describes when to use them and the form. A great way to remind yourself of all condtionals.
Zero conditional 00:34, 00:40
First conditional 01:01, 01:10
Second conditional 01:40, 01:48
Third conditional 02:22, 02:29
★ Mixed conditional 02:49, (03:02, 03:19), (03:30, 03:49
TWITTER: https://twitter.com/oxford_now
FACEBOOK: https://www.facebook.com/oxfordenglishnow
Join me on Patreon:
PATREON: patreon.com/oxfordenglishnow
English Language Grammar – Conditionals: The Zero Conditional
This video explains how to use the zero conditional form, which is used to talk about real conditions and results. Here’s an example: If I am sick, I stay home and rest. What do you do if you are sick? AmericanEnglish
To learn more English or to get additional resources for English language teaching, see:
http://www.facebook.com/AmericanEnglishatState
http://www.facebook.com/AmericanEnglishforEducators
http://americanenglish.state.gov
THE CONDITIONALS – 0,1,2 \u0026 3 Conditionals\u0026 QUIZ – English Grammar Lesson
Today we look at the 4 main English conditional sentences (0, 1st, 2nd \u0026 3rd), with lots of examples and a quiz! Download the free PDF and quiz here: http://bit.ly/ConditionalsPDF Don’t forget to complete the homework for this English grammar lesson!
Thank you to Seonaid and her wonderful website https://www.perfectenglishgrammar.com/ I’ve used her website to plan my lessons for years! It’s the best of the best when it comes to grammar explanations and exercises.
DO YOU WANT TO RECEIVE EMAILS FROM LUCY? Sign up here: https://bit.ly/EmailsFromLucy
Don’t forget to turn on subtitles if you need them! This is how I generate my subtitles (you can get a $10 subtitle coupon too): https://www.rev.com/blog/coupon/?ref=lucy (affiliate)
Visit my website for free PDFs and an interactive pronunciation tool! https://englishwithlucy.co.uk
MY SOCIAL MEDIA:
Personal Channel: http://bit.ly/LucyBella (I post subtitled vlogs of my life in the English countryside! Perfect for listening practice!)
Instagram: @Lucy http://bit.ly/lucyinsta
My British English Pronunciation Course is now LIVE: https://englishwithlucy.co.uk/pronunciationcourse (use code YOUTUBE10 for a 10% discount!)
Do you want to improve your pronunciation? I have launched my British English (Modern RP) pronunciation course! I’ll train you to read phonetic transcriptions, and produce each sound that comprises modern received pronunciation. I’ll also teach you how to implement the correct use of intonation, stress, rhythm, connected speech, and much more. We’ll compare similar sounds, and look at tricky topics like the glottal stop and the dark L.
Technically, I need to mark this as an AD even though it is my own company so AD 🙂
Want to get a copy of my English Vocabulary Planners? Click here: https://shop.englishwithlucy.co.uk The best offer is the 4book bundle where you get 4 planners for the price of 3. This product is very limited don’t miss out. The English Plan will be shipped from early August, from me here in England to you across the world! We ship internationally!
Watch my explainer video here: https://bit.ly/TheEnglishPlanVideo
Practice speaking: Earn $10 free italki credit: https://go.italki.com/englishwithlucy… (ad affiliate)
Improve listening! Free Audible audiobook: https://goo.gl/LshaPp
If you like my lessons, and would like to support me, you can buy me a coffee here: https://kofi.com/englishwithlucy
FREE £26 Airbnb credit: https://www.airbnb.co.uk/c/lcondesa (ad affiliate)
Email for business enquiries ONLY: [email protected]
Edited by La Ferpection: https://www.laferpection.com/
Zero Conditional – Conditional Sentences: Creative \u0026 engaging animated ESL video for teachers to use
Teach your students zero conditionals (conditional sentences) using this exciting, fun \u0026 interactive animated ESL video for upperintermediate learners.
If you love our videos, please support us at Patreon: https://www.patreon.com/oomongzu
WEBSITE: http://oomongzu.com
For more creative, engaging and interactive animated grammar teaching videos, please visit our website.
For the “No Music” version of this video, please click here: https://www.youtube.com/watch?v=gpvf2_Mrpg
Title of English / ESL Video:
Zero Conditionals
Target English Grammar:
Zero Conditionals:
– Conditional sentences / conditional clauses
– If clause + result clause / clauses of result
– Also known as:
– condition clause + consequence clause
– subordinate clause + main clause / other clause
– dependent clause + independent clause.
Student Proficiency Level:
Upperintermediate level grammar
Suggested Courses:
General English
Instructions:
– Play the video in class after delivering a warmup activity first.
– Pause the video whenever the narrator asks students a question to give students time to answer. For example, after elicitations and concept checking questions (CCQs).
Summary of English Grammar: Zero Conditionals – Conditional Sentences
Approximate chronological order:
Rules and Explanation:
Function:
– To talk about things which are always true or things which always happen as a result of something else. We’re not talking about a specific event, but rather something which is generally true.
Specific Uses:
– Elicitation from students.
– Facts: If I mix hydrogen with oxygen, it turns into water.
– Elicitation from students.
– General truths: If you fly with budget airlines, the drinks are expensive.
– Routines and habits: Unless I’m late for work, I always catch the train.
– Preferences: When I stir fry vegetables, I prefer olive oil.
– Rules and laws: If you’re in class, don’t use your phone.
– Cause and effects: If you eat too much junk food, you can get fat.
– Superstitions: It’s bad luck if the groom sees the bride before the wedding.
– Proverbs: When it rains, it pours!
– 0 conditionals can also be used for specific situations:
– To give instructions: If Bill comes here again, tell him I’m not scared of him!
– To offer suggestions and advice: If you go to the beach, put on lots of sunscreen.
– To make requests: If you go past the groceries store, get a few things for me please.
Concept Checking Questions (CCQs)
– 0 conditionals don’t talk about the past, present or future. They talk about things which are always true.
Form:
Statements:
– If + present simple, + present simple
– If + I mix hydrogen with water, + it turns into water.
When / Unless:
– We can use when or unless to replace if in the if clause.
– Example 1: When + I stir fry vegetables, I + prefer olive oil.
– Example 2: Unless + I’m late for work, + I always catch the train.
Modal Verbs:
– Modal verbs are common in 0 conditionals and can be used in either the if the clause or the result clause.
– Example: If + you eat too much junk food, + you can get fat.
Imperatives:
– Imperatives are common in the result clause when we:
– describe rules and laws: If you’re in class, don’t use your phone.
– give instructions: If Bill comes here again, tell him I’m not scared of him!
– offer suggestions and advice: If you go to the beach, put on lots of sunscreen.
– make requests: If you go past the groceries store, get a few things for me please.
Present Continuous / Present Progressive Tense:
– Instead of using the present simple tense, we can use the present continuous / present progressive tense in either of the clauses.
– Example 1: If you go past the groceries store, get a few things for me please.
– Example 1: If you‘re going out, get a few things for me please. (Present continuous + present simple)
– Example 2: If you eat too much junk food, you can get fat.
– Example 2: If you’re overweight, you‘re probably eating too much junk food. (Present simple + present continuous)
Present Perfect Simple Tense:
– We can also use the present perfect simple tense in either clause.
– Example 1: Unless I’m late for work, I always catch the train.
– Example 1: If you‘ve caught the train during peak hour, you know how packed the trains are. (Present perfect + present simple)
– Example 2: If you go to the beach, put on lots of sunscreen.
– Example 2: If you‘ve been to the beach, you‘ve probably been sunburned before. (Present perfect + present perfect)
Summary of Functions:
– To talk about things which are always true or things which happen as a result of something:
– Facts.
– General truths.
– Routines.
– Habits.
– Preferences.
– Rules and laws.
– Cause and effects.
– Superstitions.
– Proverbs.
– Specific situations:
– Instructions.
– Suggestions and advice.
– Requests.
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูวิธีอื่นๆMAKE MONEY ONLINE
ขอบคุณที่รับชมกระทู้ครับ conditional type 0